diff options
Diffstat (limited to 'tests')
318 files changed, 27230 insertions, 3415 deletions
diff --git a/tests/ActivityTests/res/anim/slow_enter.xml b/tests/ActivityTests/res/anim/slow_enter.xml new file mode 100644 index 0000000..0309643 --- /dev/null +++ b/tests/ActivityTests/res/anim/slow_enter.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2011, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false" > + <scale android:fromXScale="0.9" android:toXScale="1.5" + android:fromYScale="0.9" android:toYScale="1.5" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@interpolator/slow_enter" + android:duration="40000" /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:interpolator="@android:interpolator/decelerate_cubic" + android:duration="1000" /> +</set> diff --git a/tests/ActivityTests/res/anim/slow_exit.xml b/tests/ActivityTests/res/anim/slow_exit.xml new file mode 100644 index 0000000..6cd3114 --- /dev/null +++ b/tests/ActivityTests/res/anim/slow_exit.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2011, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:shareInterpolator="false" > + <scale android:fromXScale="1.0" android:toXScale="0.9" + android:fromYScale="1.0" android:toYScale="0.9" + android:pivotX="50%" android:pivotY="50%" + android:interpolator="@android:interpolator/decelerate_quint" + android:duration="300" /> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:interpolator="@android:interpolator/decelerate_cubic" + android:duration="300"/> +</set> diff --git a/tests/ActivityTests/res/interpolator/slow_enter.xml b/tests/ActivityTests/res/interpolator/slow_enter.xml new file mode 100644 index 0000000..ddab1aa --- /dev/null +++ b/tests/ActivityTests/res/interpolator/slow_enter.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2011, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" + android:cycles="10" /> diff --git a/tests/ActivityTests/res/values/themes.xml b/tests/ActivityTests/res/values/themes.xml new file mode 100644 index 0000000..67f5938 --- /dev/null +++ b/tests/ActivityTests/res/values/themes.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <style name="SlowDialog" parent="@android:style/Theme.Holo.Dialog"> + <item name="android:windowAnimationStyle">@style/SlowDialog</item> + </style> + <style name="SlowDialog"> + <item name="android:windowEnterAnimation">@anim/slow_enter</item> + <item name="android:windowExitAnimation">@anim/slow_exit</item> + </style> +</resources> diff --git a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java index 583c13c..ae42e29 100644 --- a/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java +++ b/tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java @@ -22,6 +22,7 @@ import java.util.List; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityThread; +import android.app.AlertDialog; import android.app.Application; import android.content.ActivityNotFoundException; import android.os.Bundle; @@ -35,6 +36,8 @@ import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ScrollView; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -101,6 +104,20 @@ public class ActivityTestMain extends Activity { } @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add("Animate!").setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override public boolean onMenuItemClick(MenuItem item) { + AlertDialog.Builder builder = new AlertDialog.Builder(ActivityTestMain.this, + R.style.SlowDialog); + builder.setTitle("This is a title"); + builder.show(); + return true; + } + }); + return true; + } + + @Override protected void onStart() { super.onStart(); buildUi(); diff --git a/tests/BiDiTests/Android-private.mk b/tests/BiDiTests/Android.mk index ae29fc2..ae29fc2 100644 --- a/tests/BiDiTests/Android-private.mk +++ b/tests/BiDiTests/Android.mk diff --git a/tests/BiDiTests/AndroidManifest.xml b/tests/BiDiTests/AndroidManifest.xml index c60edd8..4aead81 100644 --- a/tests/BiDiTests/AndroidManifest.xml +++ b/tests/BiDiTests/AndroidManifest.xml @@ -19,7 +19,9 @@ android:versionCode="1" android:versionName="1.0"> - <application android:label="BiDiTests" android:hardwareAccelerated="true"> + <application android:label="BiDiTests" + android:hardwareAccelerated="true" + android:supportsRtl="true" > <activity android:name=".BiDiTestActivity" android:windowSoftInputMode="stateAlwaysHidden"> diff --git a/tests/BiDiTests/res/layout/basic.xml b/tests/BiDiTests/res/layout/basic.xml index f503658..7d4d4db 100644 --- a/tests/BiDiTests/res/layout/basic.xml +++ b/tests/BiDiTests/res/layout/basic.xml @@ -19,6 +19,10 @@ android:layout_width="fill_parent" android:layout_height="fill_parent"> + <ScrollView + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -131,4 +135,6 @@ </LinearLayout> + </ScrollView> + </FrameLayout> diff --git a/tests/TileBenchmark/tests/AndroidManifest.xml b/tests/BiDiTests/res/layout/grid_layout_code.xml index 703b152..87a0ec0 100644 --- a/tests/TileBenchmark/tests/AndroidManifest.xml +++ b/tests/BiDiTests/res/layout/grid_layout_code.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 The Android Open Source Project +<!-- 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. @@ -14,14 +14,9 @@ limitations under the License. --> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.test.tilebenchmark.tests"> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/grid_layout_code" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> - <application> - <uses-library android:name="android.test.runner" /> - </application> - - <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.test.tilebenchmark" - android:label="Tests for WebView Tiles."/> -</manifest> +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/layout/grid_layout_locale.xml b/tests/BiDiTests/res/layout/grid_layout_locale.xml new file mode 100644 index 0000000..4198898 --- /dev/null +++ b/tests/BiDiTests/res/layout/grid_layout_locale.xml @@ -0,0 +1,74 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/grid_layout_locale" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + + <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:useDefaultMargins="true" + android:alignmentMode="alignBounds" + android:columnOrderPreserved="false" + android:columnCount="4" + android:layoutDirection="locale"> + + <TextView + android:text="Email setup" + android:textSize="32dip" + + android:layout_columnSpan="4" + android:layout_gravity="center_horizontal"/> + + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="16dip" + android:layout_columnSpan="4" + android:layout_gravity="left"/> + + <TextView + android:text="Email address:" + android:layout_gravity="right"/> + + <EditText + android:ems="10"/> + + <TextView + android:text="Password:" + android:layout_column="0" + android:layout_gravity="right"/> + + <EditText + android:ems="8"/> + + <Space + android:layout_row="4" + android:layout_column="0" + android:layout_columnSpan="3" + android:layout_gravity="fill" + /> + + <Button + android:text="Next" + android:layout_row="5" + android:layout_column="3"/> + + </GridLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/layout/grid_layout_ltr.xml b/tests/BiDiTests/res/layout/grid_layout_ltr.xml new file mode 100644 index 0000000..e320809 --- /dev/null +++ b/tests/BiDiTests/res/layout/grid_layout_ltr.xml @@ -0,0 +1,95 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/grid_layout_ltr" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + + <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:useDefaultMargins="true" + android:alignmentMode="alignBounds" + android:columnOrderPreserved="false" + android:columnCount="4" + android:layoutDirection="ltr"> + + <TextView + android:text="Email setup" + android:textSize="32dip" + + android:layout_columnSpan="4" + android:layout_gravity="center_horizontal"/> + + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="16dip" + android:layout_columnSpan="4" + android:layout_gravity="left"/> + + <TextView + android:text="Email address:" + android:layout_gravity="right"/> + + <EditText + android:ems="10"/> + + <TextView + android:text="Password:" + android:layout_column="0" + android:layout_gravity="right"/> + + <EditText + android:ems="8"/> + + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="16dip" + android:layout_columnSpan="4" + android:layout_gravity="start"/> + + <TextView + android:text="Email address:" + android:layout_gravity="end"/> + + <EditText + android:ems="10"/> + + <TextView + android:text="Password:" + android:layout_column="0" + android:layout_gravity="end"/> + + <EditText + android:ems="8"/> + + <Space + android:layout_row="4" + android:layout_column="0" + android:layout_columnSpan="3" + android:layout_gravity="fill" + /> + + <Button + android:text="Next" + android:layout_row="5" + android:layout_column="3"/> + + </GridLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/layout/grid_layout_rtl.xml b/tests/BiDiTests/res/layout/grid_layout_rtl.xml new file mode 100644 index 0000000..6d3aae6 --- /dev/null +++ b/tests/BiDiTests/res/layout/grid_layout_rtl.xml @@ -0,0 +1,95 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/grid_layout_rtl" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> + + + <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:useDefaultMargins="true" + android:alignmentMode="alignBounds" + android:columnOrderPreserved="false" + android:columnCount="4" + android:layoutDirection="rtl"> + + <TextView + android:text="Email setup" + android:textSize="32dip" + + android:layout_columnSpan="4" + android:layout_gravity="center_horizontal"/> + + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="16dip" + android:layout_columnSpan="4" + android:layout_gravity="left"/> + + <TextView + android:text="Email address:" + android:layout_gravity="right"/> + + <EditText + android:ems="10"/> + + <TextView + android:text="Password:" + android:layout_column="0" + android:layout_gravity="right"/> + + <EditText + android:ems="8"/> + + <TextView + android:text="You can configure email in just a few steps:" + android:textSize="16dip" + android:layout_columnSpan="4" + android:layout_gravity="end"/> + + <TextView + android:text="Email address:" + android:layout_gravity="start"/> + + <EditText + android:ems="10"/> + + <TextView + android:text="Password:" + android:layout_column="0" + android:layout_gravity="start"/> + + <EditText + android:ems="8"/> + + <Space + android:layout_row="4" + android:layout_column="0" + android:layout_columnSpan="3" + android:layout_gravity="fill" + /> + + <Button + android:text="Next" + android:layout_row="5" + android:layout_column="3"/> + + </GridLayout> + +</FrameLayout>
\ No newline at end of file diff --git a/tests/BiDiTests/res/layout/textview_alignment_ltr.xml b/tests/BiDiTests/res/layout/textview_alignment_ltr.xml new file mode 100644 index 0000000..0e1adba --- /dev/null +++ b/tests/BiDiTests/res/layout/textview_alignment_ltr.xml @@ -0,0 +1,578 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/textview_alignment_ltr" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="ltr"> + + <TableLayout android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <TableRow> + <TextView android:text="(unspecified)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity right" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity end" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="gravity" + android:gravity="center_horizontal"> + + <TextView android:text="inherit gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="center"> + + <TextView android:text="inherit gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textStart"> + + <TextView android:text="inherit textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textEnd"> + + <TextView android:text="inherit textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewStart"> + + <TextView android:text="inherit viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewEnd"> + + <TextView android:text="inherit viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + </TableLayout> + +</FrameLayout> diff --git a/tests/BiDiTests/res/layout/textview_alignment_rtl.xml b/tests/BiDiTests/res/layout/textview_alignment_rtl.xml new file mode 100644 index 0000000..12a90d5 --- /dev/null +++ b/tests/BiDiTests/res/layout/textview_alignment_rtl.xml @@ -0,0 +1,578 @@ +<?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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/textview_alignment_rtl" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layoutDirection="rtl"> + + <TableLayout android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <TableRow> + <TextView android:text="(unspecified)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity left" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="left" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity right" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="right" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity start" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="start" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity end" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="end" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="gravity center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="gravity" + android:gravity="center_horizontal" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="center" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="textEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewStart" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow> + <TextView android:text="viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="viewEnd" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="gravity" + android:gravity="center_horizontal"> + + <TextView android:text="inherit gravity (default)" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="center"> + + <TextView android:text="inherit gravity center" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textStart"> + + <TextView android:text="inherit textStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="textEnd"> + + <TextView android:text="inherit textEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewStart"> + + <TextView android:text="inherit viewStart" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + <TableRow android:textAlignment="viewEnd"> + + <TextView android:text="inherit viewEnd" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:typeface="serif" + android:layout_marginRight="7dip" + android:layout_marginLeft="7dip" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/textview_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + <TextView android:layout_height="wrap_content" + android:layout_width="200dip" + android:textSize="24dip" + android:text="@string/hebrew_text" + android:textAlignment="inherit" + android:layout_marginLeft="7dip" + android:layout_marginRight="7dip" + android:background="#444444" + /> + </TableRow> + + </TableLayout> + +</FrameLayout> diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml index b1f5e50..233cd0d 100644 --- a/tests/BiDiTests/res/values/strings.xml +++ b/tests/BiDiTests/res/values/strings.xml @@ -24,11 +24,11 @@ <string name="button_before_text">Start</string> <string name="button_requestlayout_text">Request Layout</string> <string name="button_alert_dialog_text">AlertDialog</string> - <string name="textview_text">This is a text for a TextView</string> - <string name="textview_ltr_text">This is a text for a LTR TextView</string> - <string name="textview_rtl_text">This is a text for a RTL TextView</string> - <string name="textview_default_text">This is a text for a default TextView</string> - <string name="textview_password_default_text">This is a text for a password TextView</string> + <string name="textview_text">TextView</string> + <string name="textview_ltr_text">LTR TextView</string> + <string name="textview_rtl_text">RTL TextView</string> + <string name="textview_default_text">Default TextView</string> + <string name="textview_password_default_text">Password TextView</string> <string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string> <string name="normal_text">Normal String</string> <string name="normal_long_text">mmmmmmmmmmmmmmmmmmmmmmmm</string> @@ -50,5 +50,6 @@ <string name="rtl">"والحق أن تترك ونص"</string> <string name="composing">"\u0644\u0627"</string> <string name="url">www.amazon.co.uk/gp/aw/h.html/275-8912818-8203452</string> + <string name="pointer_location" msgid="6084434787496938001">"ตำแหน่งของตัวชี้"</string> </resources> diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java index b45b98f..209597e 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java @@ -104,10 +104,26 @@ public class BiDiTestActivity extends Activity { addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas); addItem(result, "Canvas2", BiDiTestCanvas2.class, R.id.canvas2); + addItem(result, "TextView LTR", BiDiTestTextViewLtr.class, R.id.textview_ltr); + addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl); + addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale); + + addItem(result, "TextDirection LTR", BiDiTestTextViewDirectionLtr.class, R.id.textview_direction_ltr); + addItem(result, "TextDirection RTL", BiDiTestTextViewDirectionRtl.class, R.id.textview_direction_rtl); + + addItem(result, "TextAlignment LTR", BiDiTestTextViewAlignmentLtr.class, R.id.textview_alignment_ltr); + addItem(result, "TextAlignment RTL", BiDiTestTextViewAlignmentRtl.class, R.id.textview_alignment_rtl); + addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr); addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl); addItem(result, "Linear LOC", BiDiTestLinearLayoutLocale.class, R.id.linear_layout_locale); + addItem(result, "Grid LTR", BiDiTestGridLayoutLtr.class, R.id.grid_layout_ltr); + addItem(result, "Grid RTL", BiDiTestGridLayoutRtl.class, R.id.grid_layout_rtl); + addItem(result, "Grid LOC", BiDiTestGridLayoutLocale.class, R.id.grid_layout_locale); + addItem(result, "Grid C-LTR", BiDiTestGridLayoutCodeLtr.class, R.id.grid_layout_code); + addItem(result, "Grid C-RTL", BiDiTestGridLayoutCodeRtl.class, R.id.grid_layout_code); + addItem(result, "Frame LTR", BiDiTestFrameLayoutLtr.class, R.id.frame_layout_ltr); addItem(result, "Frame RTL", BiDiTestFrameLayoutRtl.class, R.id.frame_layout_rtl); addItem(result, "Frame LOC", BiDiTestFrameLayoutLocale.class, R.id.frame_layout_locale); @@ -128,15 +144,9 @@ public class BiDiTestActivity extends Activity { addItem(result, "Margin MIXED", BiDiTestViewGroupMarginMixed.class, R.id.view_group_margin_mixed); - addItem(result, "TextView LTR", BiDiTestTextViewLtr.class, R.id.textview_ltr); - addItem(result, "TextView RTL", BiDiTestTextViewRtl.class, R.id.textview_rtl); - addItem(result, "TextView LOC", BiDiTestTextViewLocale.class, R.id.textview_locale); - - addItem(result, "TextDirection LTR", BiDiTestTextViewDirectionLtr.class, R.id.textview_direction_ltr); - addItem(result, "TextDirection RTL", BiDiTestTextViewDirectionRtl.class, R.id.textview_direction_rtl); - addItem(result, "TextView Drawables LTR", BiDiTestTextViewDrawablesLtr.class, R.id.textview_drawables_ltr); addItem(result, "TextView Drawables RTL", BiDiTestTextViewDrawablesRtl.class, R.id.textview_drawables_rtl); + addItem(result, "Gallery LTR", BiDiTestGalleryLtr.class, R.id.gallery_ltr); addItem(result, "Gallery RTL", BiDiTestGalleryRtl.class, R.id.gallery_rtl); diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java new file mode 100644 index 0000000..2b5e674 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java @@ -0,0 +1,122 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.GridLayout; +import android.widget.*; + +import static android.text.InputType.*; +import static android.widget.GridLayout.*; + +public class BiDiTestGridLayoutCodeLtr extends Fragment { + + private FrameLayout currentView; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + currentView = (FrameLayout) inflater.inflate(R.layout.grid_layout_code, container, false); + return currentView; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + currentView.addView(create(currentView.getContext())); + } + + public static View create(Context context) { + GridLayout layout = new GridLayout(context); + layout.setUseDefaultMargins(true); + layout.setAlignmentMode(ALIGN_BOUNDS); + layout.setRowOrderPreserved(false); + layout.setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + + Spec row1 = spec(0); + Spec row2 = spec(1); + Spec row3 = spec(2, BASELINE); + Spec row4 = spec(3, BASELINE); + Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two + Spec row6 = spec(5); + Spec row7 = spec(6); + + Spec col1a = spec(0, 4, CENTER); + Spec col1b = spec(0, 4, LEFT); + Spec col1c = spec(0, RIGHT); + Spec col2 = spec(1, START); + Spec col3 = spec(2, FILL); + Spec col4a = spec(3); + Spec col4b = spec(3, FILL); + + { + TextView c = new TextView(context); + c.setTextSize(32); + c.setText("Email setup"); + layout.addView(c, new GridLayout.LayoutParams(row1, col1a)); + } + { + TextView c = new TextView(context); + c.setTextSize(16); + c.setText("You can configure email in just a few steps:"); + layout.addView(c, new GridLayout.LayoutParams(row2, col1b)); + } + { + TextView c = new TextView(context); + c.setText("Email address:"); + layout.addView(c, new GridLayout.LayoutParams(row3, col1c)); + } + { + EditText c = new EditText(context); + c.setEms(10); + c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + layout.addView(c, new GridLayout.LayoutParams(row3, col2)); + } + { + TextView c = new TextView(context); + c.setText("Password:"); + layout.addView(c, new GridLayout.LayoutParams(row4, col1c)); + } + { + TextView c = new EditText(context); + c.setEms(8); + c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD); + layout.addView(c, new GridLayout.LayoutParams(row4, col2)); + } + { + Space c = new Space(context); + layout.addView(c, new GridLayout.LayoutParams(row5, col3)); + } + { + Button c = new Button(context); + c.setText("Manual setup"); + layout.addView(c, new GridLayout.LayoutParams(row6, col4a)); + } + { + Button c = new Button(context); + c.setText("Next"); + layout.addView(c, new GridLayout.LayoutParams(row7, col4b)); + } + + return layout; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java new file mode 100644 index 0000000..3a03c6c --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java @@ -0,0 +1,122 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.GridLayout; +import android.widget.*; + +import static android.text.InputType.*; +import static android.widget.GridLayout.*; + +public class BiDiTestGridLayoutCodeRtl extends Fragment { + + private FrameLayout currentView; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + currentView = (FrameLayout) inflater.inflate(R.layout.grid_layout_code, container, false); + return currentView; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + currentView.addView(create(currentView.getContext())); + } + + public static View create(Context context) { + GridLayout layout = new GridLayout(context); + layout.setUseDefaultMargins(true); + layout.setAlignmentMode(ALIGN_BOUNDS); + layout.setRowOrderPreserved(false); + layout.setLayoutDirection(View.LAYOUT_DIRECTION_RTL); + + Spec row1 = spec(0); + Spec row2 = spec(1); + Spec row3 = spec(2, BASELINE); + Spec row4 = spec(3, BASELINE); + Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two + Spec row6 = spec(5); + Spec row7 = spec(6); + + Spec col1a = spec(0, 4, CENTER); + Spec col1b = spec(0, 4, LEFT); + Spec col1c = spec(0, RIGHT); + Spec col2 = spec(1, START); + Spec col3 = spec(2, FILL); + Spec col4a = spec(3); + Spec col4b = spec(3, FILL); + + { + TextView c = new TextView(context); + c.setTextSize(32); + c.setText("Email setup"); + layout.addView(c, new GridLayout.LayoutParams(row1, col1a)); + } + { + TextView c = new TextView(context); + c.setTextSize(16); + c.setText("You can configure email in just a few steps:"); + layout.addView(c, new GridLayout.LayoutParams(row2, col1b)); + } + { + TextView c = new TextView(context); + c.setText("Email address:"); + layout.addView(c, new GridLayout.LayoutParams(row3, col1c)); + } + { + EditText c = new EditText(context); + c.setEms(10); + c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + layout.addView(c, new GridLayout.LayoutParams(row3, col2)); + } + { + TextView c = new TextView(context); + c.setText("Password:"); + layout.addView(c, new GridLayout.LayoutParams(row4, col1c)); + } + { + TextView c = new EditText(context); + c.setEms(8); + c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD); + layout.addView(c, new GridLayout.LayoutParams(row4, col2)); + } + { + Space c = new Space(context); + layout.addView(c, new GridLayout.LayoutParams(row5, col3)); + } + { + Button c = new Button(context); + c.setText("Manual setup"); + layout.addView(c, new GridLayout.LayoutParams(row6, col4a)); + } + { + Button c = new Button(context); + c.setText("Next"); + layout.addView(c, new GridLayout.LayoutParams(row7, col4b)); + } + + return layout; + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLocale.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLocale.java new file mode 100644 index 0000000..16e61ad --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLocale.java @@ -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. + */ + +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestGridLayoutLocale extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.grid_layout_locale, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLtr.java new file mode 100644 index 0000000..df6c9fe --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLtr.java @@ -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. + */ + +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestGridLayoutLtr extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.grid_layout_ltr, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutRtl.java new file mode 100644 index 0000000..8bed113 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutRtl.java @@ -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. + */ + +package com.android.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestGridLayoutRtl extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.grid_layout_rtl, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java new file mode 100644 index 0000000..5ea5d81 --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java @@ -0,0 +1,31 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestTextViewAlignmentLtr extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.textview_alignment_ltr, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java new file mode 100644 index 0000000..fcc7a5d --- /dev/null +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java @@ -0,0 +1,31 @@ +/* + * 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.bidi; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +public class BiDiTestTextViewAlignmentRtl extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + return inflater.inflate(R.layout.textview_alignment_rtl, container, false); + } +} diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java index 0126dea..0b1974a 100644 --- a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java +++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java @@ -51,6 +51,7 @@ public class BiDiTestView extends View { private String MIXED_TEXT_1; private String HEBREW_TEXT; private String RTL_TEXT; + private String THAI_TEXT; private int currentTextSize; @@ -82,6 +83,7 @@ public class BiDiTestView extends View { MIXED_TEXT_1 = context.getString(R.string.mixed_text_1); HEBREW_TEXT = context.getString(R.string.hebrew_text); RTL_TEXT = context.getString(R.string.rtl); + THAI_TEXT = context.getString(R.string.pointer_location); } public void setCurrentTextSize(int size) { @@ -134,6 +136,10 @@ public class BiDiTestView extends View { // Test Hebrew deltaX = testString(canvas, RTL_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize, false, false, Paint.DIRECTION_RTL, currentTextSize); + + // Test Thai + deltaX = testString(canvas, THAI_TEXT, ORIGIN, ORIGIN + 16 * currentTextSize, + false, false, Paint.DIRECTION_LTR, currentTextSize); } private int testString(Canvas canvas, String text, int x, int y, diff --git a/tests/CoreTests/android/core/CharArrayWriterTest.java b/tests/CoreTests/android/core/CharArrayWriterTest.java deleted file mode 100644 index 0aae1e4..0000000 --- a/tests/CoreTests/android/core/CharArrayWriterTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.core; - -import junit.framework.TestCase; - -import java.io.CharArrayWriter; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * Basic tests for CharArrayWriter. - */ -public class CharArrayWriterTest extends TestCase { - - @SmallTest - public void testCharArrayWriter() throws Exception { - String str = "AbCdEfGhIjKlMnOpQrStUvWxYz"; - CharArrayWriter a = new CharArrayWriter(); - CharArrayWriter b = new CharArrayWriter(); - - a.write(str, 0, 26); - a.write('X'); - a.writeTo(b); - - assertEquals(27, a.size()); - assertEquals("AbCdEfGhIjKlMnOpQrStUvWxYzX", a.toString()); - - b.write("alphabravodelta", 5, 5); - b.append('X'); - assertEquals("AbCdEfGhIjKlMnOpQrStUvWxYzXbravoX", b.toString()); - b.append("omega"); - assertEquals("AbCdEfGhIjKlMnOpQrStUvWxYzXbravoXomega", b.toString()); - } -} diff --git a/tests/CoreTests/android/core/ClassLoaderTest.java b/tests/CoreTests/android/core/ClassLoaderTest.java deleted file mode 100644 index 5e7f5a4..0000000 --- a/tests/CoreTests/android/core/ClassLoaderTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.core; - -import junit.framework.TestCase; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import android.test.suitebuilder.annotation.Suppress; - -/** - * Test for basic ClassLoader functionality. - */ -@Suppress -public class ClassLoaderTest extends TestCase { - /* - package my.pkg; - public class CLTest { - public CLTest() {} - - public String test() { return "This is test 1"; } - } - */ - static private byte[] test1class = { - (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x31, - (byte) 0x00, (byte) 0x11, (byte) 0x0a, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x0d, (byte) 0x08, - (byte) 0x00, (byte) 0x0e, (byte) 0x07, (byte) 0x00, - (byte) 0x0f, (byte) 0x07, (byte) 0x00, (byte) 0x10, - (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x3c, - (byte) 0x69, (byte) 0x6e, (byte) 0x69, (byte) 0x74, - (byte) 0x3e, (byte) 0x01, (byte) 0x00, (byte) 0x03, - (byte) 0x28, (byte) 0x29, (byte) 0x56, (byte) 0x01, - (byte) 0x00, (byte) 0x04, (byte) 0x43, (byte) 0x6f, - (byte) 0x64, (byte) 0x65, (byte) 0x01, (byte) 0x00, - (byte) 0x0f, (byte) 0x4c, (byte) 0x69, (byte) 0x6e, - (byte) 0x65, (byte) 0x4e, (byte) 0x75, (byte) 0x6d, - (byte) 0x62, (byte) 0x65, (byte) 0x72, (byte) 0x54, - (byte) 0x61, (byte) 0x62, (byte) 0x6c, (byte) 0x65, - (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x74, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x01, - (byte) 0x00, (byte) 0x14, (byte) 0x28, (byte) 0x29, - (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, - (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, - (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, - (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e, - (byte) 0x67, (byte) 0x3b, (byte) 0x01, (byte) 0x00, - (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x75, - (byte) 0x72, (byte) 0x63, (byte) 0x65, (byte) 0x46, - (byte) 0x69, (byte) 0x6c, (byte) 0x65, (byte) 0x01, - (byte) 0x00, (byte) 0x0b, (byte) 0x43, (byte) 0x4c, - (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, - (byte) 0x2e, (byte) 0x6a, (byte) 0x61, (byte) 0x76, - (byte) 0x61, (byte) 0x0c, (byte) 0x00, (byte) 0x05, - (byte) 0x00, (byte) 0x06, (byte) 0x01, (byte) 0x00, - (byte) 0x0e, (byte) 0x54, (byte) 0x68, (byte) 0x69, - (byte) 0x73, (byte) 0x20, (byte) 0x69, (byte) 0x73, - (byte) 0x20, (byte) 0x74, (byte) 0x65, (byte) 0x73, - (byte) 0x74, (byte) 0x20, (byte) 0x31, (byte) 0x01, - (byte) 0x00, (byte) 0x0d, (byte) 0x6d, (byte) 0x79, - (byte) 0x2f, (byte) 0x70, (byte) 0x6b, (byte) 0x67, - (byte) 0x2f, (byte) 0x43, (byte) 0x4c, (byte) 0x54, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x01, - (byte) 0x00, (byte) 0x10, (byte) 0x6a, (byte) 0x61, - (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c, - (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f, - (byte) 0x4f, (byte) 0x62, (byte) 0x6a, (byte) 0x65, - (byte) 0x63, (byte) 0x74, (byte) 0x00, (byte) 0x21, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x04, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x06, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x07, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1d, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, - (byte) 0x2a, (byte) 0xb7, (byte) 0x00, (byte) 0x01, - (byte) 0xb1, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x08, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00, - (byte) 0x09, (byte) 0x00, (byte) 0x0a, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x07, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x1b, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x12, - (byte) 0x02, (byte) 0xb0, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x08, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x0c - }; - - /* - package my.pkg; - public class CLTest { - public CLTest() {} - - public String test() { return "This is test 2"; } - } - */ - static private byte[] test2class = { - (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x31, - (byte) 0x00, (byte) 0x11, (byte) 0x0a, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x0d, (byte) 0x08, - (byte) 0x00, (byte) 0x0e, (byte) 0x07, (byte) 0x00, - (byte) 0x0f, (byte) 0x07, (byte) 0x00, (byte) 0x10, - (byte) 0x01, (byte) 0x00, (byte) 0x06, (byte) 0x3c, - (byte) 0x69, (byte) 0x6e, (byte) 0x69, (byte) 0x74, - (byte) 0x3e, (byte) 0x01, (byte) 0x00, (byte) 0x03, - (byte) 0x28, (byte) 0x29, (byte) 0x56, (byte) 0x01, - (byte) 0x00, (byte) 0x04, (byte) 0x43, (byte) 0x6f, - (byte) 0x64, (byte) 0x65, (byte) 0x01, (byte) 0x00, - (byte) 0x0f, (byte) 0x4c, (byte) 0x69, (byte) 0x6e, - (byte) 0x65, (byte) 0x4e, (byte) 0x75, (byte) 0x6d, - (byte) 0x62, (byte) 0x65, (byte) 0x72, (byte) 0x54, - (byte) 0x61, (byte) 0x62, (byte) 0x6c, (byte) 0x65, - (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x74, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x01, - (byte) 0x00, (byte) 0x14, (byte) 0x28, (byte) 0x29, - (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, - (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, - (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, - (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e, - (byte) 0x67, (byte) 0x3b, (byte) 0x01, (byte) 0x00, - (byte) 0x0a, (byte) 0x53, (byte) 0x6f, (byte) 0x75, - (byte) 0x72, (byte) 0x63, (byte) 0x65, (byte) 0x46, - (byte) 0x69, (byte) 0x6c, (byte) 0x65, (byte) 0x01, - (byte) 0x00, (byte) 0x0b, (byte) 0x43, (byte) 0x4c, - (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, - (byte) 0x2e, (byte) 0x6a, (byte) 0x61, (byte) 0x76, - (byte) 0x61, (byte) 0x0c, (byte) 0x00, (byte) 0x05, - (byte) 0x00, (byte) 0x06, (byte) 0x01, (byte) 0x00, - (byte) 0x0e, (byte) 0x54, (byte) 0x68, (byte) 0x69, - (byte) 0x73, (byte) 0x20, (byte) 0x69, (byte) 0x73, - (byte) 0x20, (byte) 0x74, (byte) 0x65, (byte) 0x73, - (byte) 0x74, (byte) 0x20, (byte) 0x32, (byte) 0x01, - (byte) 0x00, (byte) 0x0d, (byte) 0x6d, (byte) 0x79, - (byte) 0x2f, (byte) 0x70, (byte) 0x6b, (byte) 0x67, - (byte) 0x2f, (byte) 0x43, (byte) 0x4c, (byte) 0x54, - (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x01, - (byte) 0x00, (byte) 0x10, (byte) 0x6a, (byte) 0x61, - (byte) 0x76, (byte) 0x61, (byte) 0x2f, (byte) 0x6c, - (byte) 0x61, (byte) 0x6e, (byte) 0x67, (byte) 0x2f, - (byte) 0x4f, (byte) 0x62, (byte) 0x6a, (byte) 0x65, - (byte) 0x63, (byte) 0x74, (byte) 0x00, (byte) 0x21, - (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x04, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x05, (byte) 0x00, (byte) 0x06, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x07, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1d, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, - (byte) 0x2a, (byte) 0xb7, (byte) 0x00, (byte) 0x01, - (byte) 0xb1, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x08, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, - (byte) 0x04, (byte) 0x00, (byte) 0x01, (byte) 0x00, - (byte) 0x09, (byte) 0x00, (byte) 0x0a, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x07, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x1b, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x00, - (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x12, - (byte) 0x02, (byte) 0xb0, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x08, - (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, - (byte) 0x00, (byte) 0x0b, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x0c - }; - - /* - * Custom class loader. - */ - private class MyLoader extends ClassLoader { - public MyLoader(byte[] data) { - super(); - mData = data; - } - - protected Class<?> findClass(String name) throws ClassNotFoundException { - assertEquals("my.pkg.CLTest", name); - return defineClass(name, mData, 0, mData.length); - } - - byte[] mData; - } - - - /* - * Simple test: manually load two class files that have the same class - * name but different contents. - */ - public void testClassLoader() throws Exception { - Class test1, test2; - MyLoader loader1 = new MyLoader(test1class); - MyLoader loader2 = new MyLoader(test2class); - - test1 = loader1.loadClass("my.pkg.CLTest"); - test2 = loader2.loadClass("my.pkg.CLTest"); - - methodTest(test1, "This is test 1"); - methodTest(test2, "This is test 2"); - } - - /* - * Invoke the test() method and verify that the string returned - * matches what we expect. - */ - private static void methodTest(Class clazz, String expect) - throws NoSuchMethodException, InstantiationException, - IllegalAccessException, InvocationTargetException { - Method meth = clazz.getMethod("test", (Class[]) null); - Object obj = clazz.newInstance(); - Object result = meth.invoke(obj, (Object[]) null); - - assertEquals(result, expect); - } -} - diff --git a/tests/CoreTests/android/core/ClassTest.java b/tests/CoreTests/android/core/ClassTest.java deleted file mode 100644 index cc1b4ca..0000000 --- a/tests/CoreTests/android/core/ClassTest.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.core; - -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; -import android.widget.Button; -import junit.framework.TestCase; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.Set; - - -class ClassWithPrivateConstructor { - private ClassWithPrivateConstructor() { - } -} - -public class ClassTest extends TestCase { - - @SmallTest - public void testClass() throws Exception { - // Now, never mind the fact that most of this stuff has to work - // for the test harness to get this far.... - - //System.out.println("Class.forName()"); - Class helloClass = Class.forName(ClassTest.class.getName()); - - //System.out.println("Class.newInstance()"); - Object instance = helloClass.newInstance(); - assertNotNull(instance); - - //System.out.println("Class.forName() nonexisting class"); - try { - Class.forName("this.class.DoesNotExist"); - fail("unexpected success"); - } catch (ClassNotFoundException ex) { - // expected - } - - //System.out.println("Class.newInstance() private constructor"); - try { - Class.forName("android.core.ClassWithPrivateConstructor").newInstance(); - fail("unexpected success"); - } catch (IllegalAccessException ex) { - // this is expected - } - - //System.out.println("Class.getDeclaredMethod()"); - - Method method = helloClass.getDeclaredMethod("method", (Class[]) null); - - method.invoke(new ClassTest(), (Object[]) null); - - //System.out.println("Class.getDeclaredMethod() w/ args"); - - method = helloClass.getDeclaredMethod("methodWithArgs", Object.class); - - Object invokeArgs[] = new Object[1]; - invokeArgs[0] = "Hello"; - Object ret = method.invoke(new ClassTest(), invokeArgs); - assertEquals(ret, invokeArgs[0]); - - //System.out.println("Class.getDeclaredMethod() -- private"); - - method = helloClass.getDeclaredMethod("privateMethod", (Class[]) null); - - method.invoke(new ClassTest(), (Object[]) null); - //fail("unexpected success"); - // TODO: I think this actually *should* succeed, because the - // call to the private method is being made from the same class. - // This needs to be replaced with a private call to a different - // class. - - //System.out.println("Class.getSuperclass"); - Class objectClass = Class.forName("java.lang.Object"); - assertEquals(helloClass.getSuperclass().getSuperclass().getSuperclass(), objectClass); - - //System.out.println("Class.isAssignableFrom"); - assertTrue(objectClass.isAssignableFrom(helloClass)); - assertFalse(helloClass.isAssignableFrom(objectClass)); - - //System.out.println("Class.getConstructor"); - - Constructor constructor = helloClass.getConstructor((Class[]) null); - assertNotNull(constructor); - - //System.out.println("Class.getModifiers"); - - assertTrue(Modifier.isPublic(helloClass.getModifiers())); - //System.out.println("Modifiers: " + Modifier.toString(helloClass.getModifiers())); - - //System.out.println("Class.getMethod"); - - helloClass.getMethod("method", (Class[]) null); - - try { - Class[] argTypes = new Class[1]; - argTypes[0] = helloClass; - helloClass.getMethod("method", argTypes); - fail("unexpected success"); - } catch (NoSuchMethodException ex) { - // exception expected - } - - // Test for public tracker issue 14 - SimpleClass obj = new SimpleClass(); - Field field = obj.getClass().getDeclaredField("str"); - field.set(obj, null); - } - - public class SimpleClass { - public String str; - } - - public Object methodWithArgs(Object o) { - return o; - } - - boolean methodInvoked; - - public void method() { - methodInvoked = true; - } - - boolean privateMethodInvoked; - - public void privateMethod() { - privateMethodInvoked = true; - } - - // Regression for 1018067: Class.getMethods() returns the same method over - // and over again from all base classes - @MediumTest - public void testClassGetMethodsNoDupes() { - Method[] methods = Button.class.getMethods(); - Set<String> set = new HashSet<String>(); - - for (int i = 0; i < methods.length; i++) { - String signature = methods[i].toString(); - - int par = signature.indexOf('('); - int dot = signature.lastIndexOf('.', par); - - signature = signature.substring(dot + 1); - - assertFalse("Duplicate " + signature, set.contains(signature)); - set.add(signature); - } - } - - interface MyInterface { - void foo(); - } - - interface MyOtherInterface extends MyInterface { - void bar(); - } - - abstract class MyClass implements MyOtherInterface { - public void gabba() { - } - - public void hey() { - } - } - - // Check if we also reflect methods from interfaces - @SmallTest - public void testGetMethodsInterfaces() { - Method[] methods = MyInterface.class.getMethods(); - assertTrue("Interface method must be there", hasMethod(methods, ".foo(")); - - methods = MyOtherInterface.class.getMethods(); - assertTrue("Interface method must be there", hasMethod(methods, ".foo(")); - assertTrue("Interface method must be there", hasMethod(methods, ".bar(")); - - methods = MyClass.class.getMethods(); - assertTrue("Interface method must be there", hasMethod(methods, ".foo(")); - assertTrue("Interface method must be there", hasMethod(methods, ".bar(")); - - assertTrue("Declared method must be there", hasMethod(methods, ".gabba(")); - assertTrue("Declared method must be there", hasMethod(methods, ".hey(")); - - assertTrue("Inherited method must be there", hasMethod(methods, ".toString(")); - } - - private boolean hasMethod(Method[] methods, String signature) { - for (int i = 0; i < methods.length; i++) { - if (methods[i].toString().contains(signature)) { - return true; - } - } - - return false; - } - - // Test for Class.getPackage(); - @SmallTest - public void testClassGetPackage() { - assertNotNull("Package must be non-null", getClass().getPackage()); - assertEquals("Package must have expected name", "android.core", getClass().getPackage().getName()); - assertEquals("Package must have expected title", "Unknown", getClass().getPackage().getSpecificationTitle()); - - Package p = java.lang.Object.class.getPackage(); - assertNotNull("Package must be non-null", p); - assertEquals("Package must have expected name", "java.lang", p.getName()); - assertSame("Package object must be same for each call", p, java.lang.Object.class.getPackage()); - } - - // Regression test for #1123708: Problem with getCanonicalName(), - // getSimpleName(), and getPackage(). - // - // A couple of interesting cases need to be checked: Top-level classes, - // member classes, local classes, and anonymous classes. Also, boundary - // cases with '$' in the class names are checked, since the '$' is used - // as the separator between outer and inner class, so this might lead - // to problems (it did in the previous implementation). - // - // Caution: Adding local or anonymous classes elsewhere in this - // file might affect the test. - private class MemberClass { - // This space intentionally left blank. - } - - private class Mi$o$oup { - // This space intentionally left blank. - } - - @SmallTest - public void testVariousClassNames() { - Class<?> clazz = this.getClass(); - String pkg = (clazz.getPackage() == null ? "" : clazz.getPackage().getName() + "."); - - // Simple, top-level class - - assertEquals("Top-level class name must be correct", pkg + "ClassTest", clazz.getName()); - assertEquals("Top-level class simple name must be correct", "ClassTest", clazz.getSimpleName()); - assertEquals("Top-level class canonical name must be correct", pkg + "ClassTest", clazz.getCanonicalName()); - - clazz = MemberClass.class; - - assertEquals("Member class name must be correct", pkg + "ClassTest$MemberClass", clazz.getName()); - assertEquals("Member class simple name must be correct", "MemberClass", clazz.getSimpleName()); - assertEquals("Member class canonical name must be correct", pkg + "ClassTest.MemberClass", clazz.getCanonicalName()); - - class LocalClass { - // This space intentionally left blank. - } - - clazz = LocalClass.class; - - assertEquals("Local class name must be correct", pkg + "ClassTest$1LocalClass", clazz.getName()); - assertEquals("Local class simple name must be correct", "LocalClass", clazz.getSimpleName()); - assertNull("Local class canonical name must be null", clazz.getCanonicalName()); - - clazz = new Object() { }.getClass(); - - assertEquals("Anonymous class name must be correct", pkg + "ClassTest$1", clazz.getName()); - assertEquals("Anonymous class simple name must be empty", "", clazz.getSimpleName()); - assertNull("Anonymous class canonical name must be null", clazz.getCanonicalName()); - - // Weird special cases with dollar in name. - - clazz = Mou$$aka.class; - - assertEquals("Top-level class name must be correct", pkg + "Mou$$aka", clazz.getName()); - assertEquals("Top-level class simple name must be correct", "Mou$$aka", clazz.getSimpleName()); - assertEquals("Top-level class canonical name must be correct", pkg + "Mou$$aka", clazz.getCanonicalName()); - - clazz = Mi$o$oup.class; - - assertEquals("Member class name must be correct", pkg + "ClassTest$Mi$o$oup", clazz.getName()); - assertEquals("Member class simple name must be correct", "Mi$o$oup", clazz.getSimpleName()); - assertEquals("Member class canonical name must be correct", pkg + "ClassTest.Mi$o$oup", clazz.getCanonicalName()); - - class Ma$hedPotatoe$ { - // This space intentionally left blank. - } - - clazz = Ma$hedPotatoe$.class; - - assertEquals("Member class name must be correct", pkg + "ClassTest$1Ma$hedPotatoe$", clazz.getName()); - assertEquals("Member class simple name must be correct", "Ma$hedPotatoe$", clazz.getSimpleName()); - assertNull("Member class canonical name must be null", clazz.getCanonicalName()); - } - - @SmallTest - public void testLocalMemberClass() { - Class<?> clazz = this.getClass(); - - assertFalse("Class must not be member", clazz.isMemberClass()); - assertFalse("Class must not be local", clazz.isLocalClass()); - - clazz = MemberClass.class; - - assertTrue("Class must be member", clazz.isMemberClass()); - assertFalse("Class must not be local", clazz.isLocalClass()); - - class OtherLocalClass { - // This space intentionally left blank. - } - - clazz = OtherLocalClass.class; - - assertFalse("Class must not be member", clazz.isMemberClass()); - assertTrue("Class must be local", clazz.isLocalClass()); - - clazz = new Object() { }.getClass(); - - assertFalse("Class must not be member", clazz.isMemberClass()); - assertFalse("Class must not be local", clazz.isLocalClass()); - } - -} - -class Mou$$aka { - // This space intentionally left blank. -} diff --git a/tests/CoreTests/android/core/MiscRegressionTest.java b/tests/CoreTests/android/core/MiscRegressionTest.java index 7734397..32995b5 100644 --- a/tests/CoreTests/android/core/MiscRegressionTest.java +++ b/tests/CoreTests/android/core/MiscRegressionTest.java @@ -16,56 +16,12 @@ package android.core; -import junit.framework.Assert; -import junit.framework.TestCase; - -import java.io.File; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.security.KeyStore; -import java.security.cert.Certificate; -import java.util.Arrays; -import java.util.ConcurrentModificationException; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Random; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.logging.Logger; -import java.util.zip.Deflater; -import java.util.zip.Inflater; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; -import android.test.suitebuilder.annotation.LargeTest; +import java.util.logging.Logger; +import junit.framework.TestCase; public class MiscRegressionTest extends TestCase { - // Regression test for #857840: want JKS key store - @SmallTest - public void testDefaultKeystore() { - String type = KeyStore.getDefaultType(); - Assert.assertEquals("Default keystore type must be Bouncy Castle", "BKS", type); - - try { - KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); - Assert.assertNotNull("Keystore must not be null", store); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - try { - KeyStore store = KeyStore.getInstance("BKS"); - Assert.assertNotNull("Keystore must not be null", store); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - // Regression test for #951285: Suitable LogHandler should be chosen // depending on the environment. @MediumTest @@ -78,408 +34,4 @@ public class MiscRegressionTest extends TestCase { Logger.global.finer("This has logging Level.FINER, should become VERBOSE"); Logger.global.finest("This has logging Level.FINEST, should become VERBOSE"); } - - // Regression test for Issue 5697: - // getContextClassLoader returns a non-application classloader - // http://code.google.com/p/android/issues/detail?id=5697 - // - @MediumTest - public void testJavaContextClassLoader() throws Exception { - Assert.assertNotNull("Must hava a Java context ClassLoader", - Thread.currentThread().getContextClassLoader()); - } - - // Regression test for #1045939: Different output for Method.toString() - @SmallTest - public void testMethodToString() { - try { - Method m1 = Object.class.getMethod("notify", new Class[] { }); - Method m2 = Object.class.getMethod("toString", new Class[] { }); - Method m3 = Object.class.getMethod("wait", new Class[] { long.class, int.class }); - Method m4 = Object.class.getMethod("equals", new Class[] { Object.class }); - Method m5 = String.class.getMethod("valueOf", new Class[] { char[].class }); - Method m6 = Runtime.class.getMethod("exec", new Class[] { String[].class }); - - assertEquals("Method.toString() must match expectations", - "public final native void java.lang.Object.notify()", - m1.toString()); - - assertEquals("Method.toString() must match expectations", - "public java.lang.String java.lang.Object.toString()", - m2.toString()); - - assertEquals("Method.toString() must match expectations", - "public final native void java.lang.Object.wait(long,int) throws java.lang.InterruptedException", - m3.toString()); - - assertEquals("Method.toString() must match expectations", - "public boolean java.lang.Object.equals(java.lang.Object)", - m4.toString()); - - assertEquals("Method.toString() must match expectations", - "public static java.lang.String java.lang.String.valueOf(char[])", - m5.toString()); - - assertEquals("Method.toString() must match expectations", - "public java.lang.Process java.lang.Runtime.exec(java.lang.String[]) throws java.io.IOException", - m6.toString()); - - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - } - - // Regression test for #1062200: Enum fails to deserialize. Actual problem - // was that Class.isEnum() erroneously returned true for indirect - // descendants of Enum. - enum TrafficLights { - RED, - YELLOW {}, - GREEN { - @SuppressWarnings("unused") - int i; - @SuppressWarnings("unused") - void foobar() {} - }; - } - - @SmallTest - public void testClassIsEnum() { - Class<?> trafficClass = TrafficLights.class; - - Class<?> redClass = TrafficLights.RED.getClass(); - Class<?> yellowClass = TrafficLights.YELLOW.getClass(); - Class<?> greenClass = TrafficLights.GREEN.getClass(); - - Assert.assertSame("Classes must be equal", trafficClass, redClass); - Assert.assertNotSame("Classes must be different", trafficClass, yellowClass); - Assert.assertNotSame("Classes must be different", trafficClass, greenClass); - Assert.assertNotSame("Classes must be different", yellowClass, greenClass); - - Assert.assertTrue("Must be an enum", trafficClass.isEnum()); - Assert.assertTrue("Must be an enum", redClass.isEnum()); - Assert.assertFalse("Must not be an enum", yellowClass.isEnum()); - Assert.assertFalse("Must not be an enum", greenClass.isEnum()); - - Assert.assertNotNull("Must have enum constants", trafficClass.getEnumConstants()); - Assert.assertNull("Must not have enum constants", yellowClass.getEnumConstants()); - Assert.assertNull("Must not have enum constants", greenClass.getEnumConstants()); - } - - // Regression test for #1046174: JarEntry.getCertificates() is really slow. - public void checkJarCertificates(File file) { - try { - JarFile jarFile = new JarFile(file); - JarEntry je = jarFile.getJarEntry("AndroidManifest.xml"); - byte[] readBuffer = new byte[1024]; - - long t0 = System.currentTimeMillis(); - - // We must read the stream for the JarEntry to retrieve - // its certificates. - InputStream is = jarFile.getInputStream(je); - while (is.read(readBuffer, 0, readBuffer.length) != -1) { - // not using - } - is.close(); - Certificate[] certs = je != null ? je.getCertificates() : null; - - long t1 = System.currentTimeMillis(); - android.util.Log.d("TestHarness", "loadCertificates() took " + (t1 - t0) + " ms"); - if (certs == null) { - android.util.Log.d("TestHarness", "We have no certificates"); - } else { - android.util.Log.d("TestHarness", "We have " + certs.length + " certificates"); - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - @LargeTest - public void testJarCertificates() { - File[] files = new File("/system/app").listFiles(); - for (int i = 0; i < files.length; i++) { - checkJarCertificates(files[i]); - } - } - - // Regression test for #1120750: Reflection for static long fields is broken - private static final long MY_LONG = 5073258162644648461L; - - @SmallTest - public void testLongFieldReflection() { - try { - Field field = getClass().getDeclaredField("MY_LONG"); - assertEquals(5073258162644648461L, field.getLong(null)); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - // Regression test for Harmony LinkedHashMap bug. Copied from core, just - // to make sure it doesn't get lost. - @SmallTest - public void testLinkedHashMap() { - // we want to test the LinkedHashMap in access ordering mode. - LinkedHashMap map = new LinkedHashMap<String, String>(10, 0.75f, true); - - map.put("key1", "value1"); - map.put("key2", "value2"); - map.put("key3", "value3"); - - Iterator iterator = map.keySet().iterator(); - String id = (String) iterator.next(); - map.get(id); - try { - iterator.next(); - // A LinkedHashMap is supposed to throw this Exception when a - // iterator.next() Operation takes place after a get - // Operation. This is because the get Operation is considered - // a structural modification if the LinkedHashMap is in - // access order mode. - fail("expected ConcurrentModificationException was not thrown."); - } catch(ConcurrentModificationException e) { - // expected - } - - LinkedHashMap mapClone = (LinkedHashMap) map.clone(); - - iterator = map.keySet().iterator(); - id = (String) iterator.next(); - mapClone.get(id); - try { - iterator.next(); - } catch(ConcurrentModificationException e) { - fail("expected ConcurrentModificationException was not thrown."); - } - } - - // Regression test for #1212257: Boot-time package scan is slow. Not - // expected to fail. Please see log if you are interested in the results. - @LargeTest - public void testZipStressManifest() { - android.util.Log.d("MiscRegressionTest", "ZIP stress test started"); - - long time0 = System.currentTimeMillis(); - - try { - File[] files = new File("/system/app").listFiles(); - - byte[] buffer = new byte[512]; - - if (files != null) { - for (int i = 0; i < files.length; i++) { - android.util.Log.d("MiscRegressionTest", - "ZIP stress test processing " + files[i] + "..."); - - ZipFile zip = new ZipFile(files[i]); - - ZipEntry entry = zip.getEntry("AndroidManifest.xml"); - InputStream stream = zip.getInputStream(entry); - - int j = stream.read(buffer); - while (j != -1) { - j = stream.read(buffer); - } - - stream.close(); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - long time1 = System.currentTimeMillis(); - - android.util.Log.d("MiscRegressionTest", "ZIP stress test finished, " + - "time was " + (time1- time0) + "ms"); - } - - @LargeTest - public void testZipStressAllFiles() { - android.util.Log.d("MiscRegressionTest", "ZIP stress test started"); - - long time0 = System.currentTimeMillis(); - - try { - File[] files = new File("/system/app").listFiles(); - - byte[] buffer = new byte[512]; - - if (files != null) { - for (int i = 0; i < files.length; i++) { - android.util.Log.d("MiscRegressionTest", - "ZIP stress test processing " + files[i] + "..."); - - ZipFile zip = new ZipFile(files[i]); - - Enumeration<? extends ZipEntry> entries = zip.entries(); - while (entries.hasMoreElements()) { - InputStream stream = zip.getInputStream(entries.nextElement()); - - int j = stream.read(buffer); - while (j != -1) { - j = stream.read(buffer); - } - - stream.close(); - } - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - - long time1 = System.currentTimeMillis(); - - android.util.Log.d("MiscRegressionTest", "ZIP stress test finished, " + - "time was " + (time1- time0) + "ms"); - } - - @SmallTest - public void testOsEncodingProperty() { - long time0 = System.currentTimeMillis(); - String[] files = new File("/system/app").list(); - long time1 = System.currentTimeMillis(); - android.util.Log.d("MiscRegressionTest", "File.list() test finished, " + - "time was " + (time1- time0) + "ms"); - } - - // ------------------------------------------------------------------------- - // Regression test for #1185084: Native memory allocated by - // java.util.zip.Deflater in system_server. The fix reduced some internal - // ZLIB buffers in size, so this test is trying to execute a lot of - // deflating to ensure that things are still working properly. - private void assertEquals(byte[] a, byte[] b) { - assertEquals("Arrays must have same length", a.length, b.length); - - for (int i = 0; i < a.length; i++) { - assertEquals("Array elements #" + i + " must be equal", a[i], b[i]); - } - } - - @LargeTest - public void testZipDeflateInflateStress() { - - final int DATA_SIZE = 16384; - - Random random = new Random(42); // Seed makes test reproducible - - try { - // Outer loop selects "mode" of test. - for (int j = 1; j <=2 ; j++) { - - byte[] input = new byte[DATA_SIZE]; - - if (j == 1) { - // Totally random content - random.nextBytes(input); - } else { - // Random contents with longer repetitions - int pos = 0; - while (pos < input.length) { - byte what = (byte)random.nextInt(256); - int howMany = random.nextInt(32); - if (pos + howMany >= input.length) { - howMany = input.length - pos; - } - Arrays.fill(input, pos, pos + howMany, what); - pos += howMany; - } - } - - // Inner loop tries all 9 compression levels. - for (int i = 1; i <= 9; i++) { - android.util.Log.d("MiscRegressionTest", "ZipDeflateInflateStress test (" + j + "," + i + ")..."); - - byte[] zipped = new byte[2 * DATA_SIZE]; // Just to make sure... - - Deflater deflater = new Deflater(i); - deflater.setInput(input); - deflater.finish(); - - deflater.deflate(zipped); - - byte[] output = new byte[DATA_SIZE]; - - Inflater inflater = new Inflater(); - inflater.setInput(zipped); - inflater.finished(); - - inflater.inflate(output); - - assertEquals(input, output); - } - } - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - // ------------------------------------------------------------------------- - // Regression test for #1252043: Thread.getStackTrace() is broken - class MyThread extends Thread { - public MyThread(String name) { - super(name); - } - - @Override - public void run() { - doSomething(); - } - - public void doSomething() { - for (int i = 0; i < 20;) { - try { - Thread.sleep(100); - } catch (InterruptedException ex) { - } - } - } - } - - class MyOtherThread extends Thread { - public int visibleTraces; - - public MyOtherThread(ThreadGroup group, String name) { - super(group, name); - } - - @Override - public void run() { - visibleTraces = Thread.getAllStackTraces().size(); - } - } - - @LargeTest - public void testThreadGetStackTrace() { - MyThread t1 = new MyThread("t1"); - t1.start(); - - try { - Thread.sleep(1000); - } catch (InterruptedException ex) { - } - - StackTraceElement[] traces = t1.getStackTrace(); - StackTraceElement trace = traces[traces.length - 2]; - - // Expect to find MyThread.doSomething in the trace - assertTrue("Must find MyThread.doSomething in trace", - trace.getClassName().endsWith("$MyThread") && - trace.getMethodName().equals("doSomething")); - - ThreadGroup g1 = new ThreadGroup("1"); - MyOtherThread t2 = new MyOtherThread(g1, "t2"); - t2.start(); - try { - t2.join(); - } catch (InterruptedException ex) { - } - - // Expect to see the traces of all threads (not just t2) - assertTrue("Must have traces for all threads", t2.visibleTraces > 1); - } } diff --git a/tests/CoreTests/android/core/RegexTest.java b/tests/CoreTests/android/core/RegexTest.java deleted file mode 100644 index 743afc1..0000000 --- a/tests/CoreTests/android/core/RegexTest.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.core; - -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.TestCase; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Tests basic functionality of Pattern and Matcher classes. - */ -public class RegexTest extends TestCase { - - @SmallTest - public void testMatches() throws Exception { - /* Tests class Matcher */ - - Pattern p = Pattern.compile("bcd"); - Matcher m = p.matcher("bcd"); - assertTrue("Should match.", m.matches()); - - /* Pattern in the middle */ - p = Pattern.compile("bcd"); - m = p.matcher("abcdefg"); - assertFalse("Should not match.", m.matches()); - - /* Pattern at the head */ - m = p.matcher("bcdefg"); - assertFalse("Should not match.", m.matches()); - - /* Pattern at the tail */ - m = p.matcher("abcd"); - assertFalse("Should not match.", m.matches()); - - /* Make sure matches() doesn't change after calls to find() */ - p = Pattern.compile(".*"); - m = p.matcher("abc"); - assertTrue(m.matches()); - assertTrue(m.find()); - assertTrue(m.matches()); - - p = Pattern.compile("."); - m = p.matcher("abc"); - assertFalse(m.matches()); - assertTrue(m.find()); - assertFalse(m.matches()); - - /* Make sure matches() agrees after a reset() */ - m.reset("z"); - assertTrue(m.matches()); - - m.reset("xyz"); - assertFalse(m.matches()); - - /* Tests class Pattern */ - - assertFalse("Erroneously matched partial string. " + - "See http://b/issue?id=754601", Pattern.matches("er", "xer")); - assertFalse("Erroneously matched partial string. " + - "See http://b/issue?id=754601", Pattern.matches("xe", "xer")); - assertTrue("Generic regex should match.", - Pattern.matches(".*", "bcd")); - assertTrue("Grouped regex should match.", - Pattern.matches("(b(c(d)))", "bcd")); - assertTrue("Grouped regex should match.", - Pattern.matches("(b)(c)(d)", "bcd")); - } - - @SmallTest - public void testGroupCount() throws Exception { - Pattern p = Pattern.compile( - "\\b(?:\\+?1)?" - + "(?:[ -\\.])?" - + "\\(?(\\d{3})?\\)?" - + "(?:[ -\\.\\/])?" - + "(\\d{3})" - + "(?:[ -\\.])?" - + "(\\d{4})\\b" - ); - - Matcher m = p.matcher("1 (919) 555-1212"); - - assertEquals("groupCount is incorrect, see http://b/issue?id=759412", - 3, m.groupCount()); - } - - @SmallTest - public void testGroups() throws Exception { - Pattern p = Pattern.compile("(b)([c|d])(z*)"); - Matcher m = p.matcher("abcdefg"); - - /* Must call find() first, otherwise group*() are undefined. */ - assertTrue(m.find()); - - assertEquals(3, m.groupCount()); - - assertEquals("bc", m.group(0)); - assertEquals("b", m.group(1)); - assertEquals("c", m.group(2)); - assertEquals("", m.group(3)); - } - - @SmallTest - public void testFind() throws Exception { - Pattern p = Pattern.compile("."); - Matcher m = p.matcher("abc"); - - assertTrue(m.find()); - assertEquals("a", m.group(0)); - - assertTrue(m.find()); - assertEquals("b", m.group(0)); - - assertTrue(m.find()); - assertEquals("c", m.group(0)); - - assertFalse(m.find()); - } - - @SmallTest - public void testReplaceAll() throws Exception { - // Begins with non-matching text, ends with matching text - Pattern p = Pattern.compile("a*b"); - Matcher m = p.matcher("fooaabfooaabfooabfoob"); - - String r = m.replaceAll("-"); - assertEquals("foo-foo-foo-foo-", r); - - // Begins with matching text, ends with non-matching text - p = Pattern.compile("a*b"); - m = p.matcher("aabfooaabfooabfoobfoo"); - - r = m.replaceAll("-"); - assertEquals("-foo-foo-foo-foo", r); - } - - @SmallTest - public void testReplaceFirst() throws Exception { - // Begins with non-matching text, ends with matching text - Pattern p = Pattern.compile("a*b"); - Matcher m = p.matcher("fooaabfooaabfooabfoob"); - - String r = m.replaceFirst("-"); - assertEquals("foo-fooaabfooabfoob", r); - - // Begins with matching text, ends with non-matching text - p = Pattern.compile("a*b"); - m = p.matcher("aabfooaabfooabfoobfoo"); - - r = m.replaceFirst("-"); - assertEquals("-fooaabfooabfoobfoo", r); - } - - @SmallTest - public void testSplit() throws Exception { - Pattern p = Pattern.compile(":"); - String[] strings; - - strings = p.split("boo:and:foo"); - assertEquals(3, strings.length); - assertEquals("boo", strings[0]); - assertEquals("and", strings[1]); - assertEquals("foo", strings[2]); - - strings = p.split("boo:and:foo", 2); - assertEquals(2, strings.length); - assertEquals("boo", strings[0]); - assertEquals("and:foo", strings[1]); - - strings = p.split("boo:and:foo", 5); - assertEquals(3, strings.length); - assertEquals("boo", strings[0]); - assertEquals("and", strings[1]); - assertEquals("foo", strings[2]); - - strings = p.split("boo:and:foo", -2); - assertEquals(3, strings.length); - assertEquals("boo", strings[0]); - assertEquals("and", strings[1]); - assertEquals("foo", strings[2]); - - p = Pattern.compile("o"); - - strings = p.split("boo:and:foo"); - assertEquals(3, strings.length); - assertEquals("b", strings[0]); - assertEquals("", strings[1]); - assertEquals(":and:f", strings[2]); - - strings = p.split("boo:and:foo", 5); - assertEquals(5, strings.length); - assertEquals("b", strings[0]); - assertEquals("", strings[1]); - assertEquals(":and:f", strings[2]); - assertEquals("", strings[3]); - assertEquals("", strings[4]); - - strings = p.split("boo:and:foo", -2); - assertEquals(5, strings.length); - assertEquals("b", strings[0]); - assertEquals("", strings[1]); - assertEquals(":and:f", strings[2]); - assertEquals("", strings[3]); - assertEquals("", strings[4]); - - strings = p.split("boo:and:foo", 0); - assertEquals(3, strings.length); - assertEquals("b", strings[0]); - assertEquals("", strings[1]); - assertEquals(":and:f", strings[2]); - } - - // ------------------------------------------------------------------- - // Regression test for #1172774: Bug in Regex.java - // Regression test for #1216887: Regular expression match is very slow - public static final Pattern TOP_LEVEL_DOMAIN_PATTERN = Pattern.compile( - "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])" - + "|(biz|b[abdefghijmnorstvwyz])" - + "|(cat|com|coop|c[acdfghiklmnoruvxyz])" - + "|d[ejkmoz]" - + "|(edu|e[cegrstu])" - + "|f[ijkmor]" - + "|(gov|g[abdefghilmnpqrstuwy])" - + "|h[kmnrtu]" - + "|(info|int|i[delmnoqrst])" - + "|(jobs|j[emop])" - + "|k[eghimnrwyz]" - + "|l[abcikrstuvy]" - + "|(mil|mobi|museum|m[acdghklmnopqrstuvwxyz])" - + "|(name|net|n[acefgilopruz])" - + "|(org|om)" - + "|(pro|p[aefghklmnrstwy])" - + "|qa" - + "|r[eouw]" - + "|s[abcdeghijklmnortuvyz]" - + "|(tel|travel|t[cdfghjklmnoprtvwz])" - + "|u[agkmsyz]" - + "|v[aceginu]" - + "|w[fs]" - + "|y[etu]" - + "|z[amw])"); - - public static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile( - "[\\+a-zA-Z0-9\\.\\_\\%\\-]+\\@" - + "((" - + "[a-zA-Z0-9]\\.|" - + "([a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9]\\.)+)" - + TOP_LEVEL_DOMAIN_PATTERN - + ")"); - - @SmallTest - public void testMonsterRegexCorrectness() { - assertTrue(EMAIL_ADDRESS_PATTERN.matcher("a+b@gmail.com").matches()); - } - - @SmallTest - public void testMonsterRegexPerformance() { - android.util.Log.e("RegexTest", "RegEx performance test started."); - long t0 = System.currentTimeMillis(); - Matcher m = EMAIL_ADDRESS_PATTERN.matcher("donot repeate@RC8jjjjjjjjjjjjjjj"); - assertFalse(m.find()); - long t1 = System.currentTimeMillis(); - android.util.Log.e("RegexTest", "RegEx performance test finished, " + - "took " + (t1 - t0) + " ms."); - } - - // - // ------------------------------------------------------------------- - -} diff --git a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java index a13c0c9..919e2b3 100644 --- a/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java +++ b/tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java @@ -17,15 +17,16 @@ package com.android.tests.dataidle; import android.content.Context; import android.net.INetworkStatsService; +import android.net.INetworkStatsSession; +import android.net.NetworkStats; import android.net.NetworkStats.Entry; import android.net.NetworkTemplate; -import android.net.NetworkStats; +import android.net.TrafficStats; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.TelephonyManager; import android.test.InstrumentationTestCase; -import android.test.InstrumentationTestRunner; import android.util.Log; /** @@ -52,7 +53,7 @@ public class DataIdleTest extends InstrumentationTestCase { * Test that dumps all the data usage metrics for wifi to instrumentation out. */ public void testWifiIdle() { - NetworkTemplate template = NetworkTemplate.buildTemplateWifi(); + NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard(); fetchStats(template); } @@ -71,13 +72,17 @@ public class DataIdleTest extends InstrumentationTestCase { * @param template {link {@link NetworkTemplate} to match. */ private void fetchStats(NetworkTemplate template) { + INetworkStatsSession session = null; try { mStatsService.forceUpdate(); - NetworkStats stats = mStatsService.getSummaryForAllUid(template, Long.MIN_VALUE, - Long.MAX_VALUE, false); + session = mStatsService.openSession(); + final NetworkStats stats = session.getSummaryForAllUid( + template, Long.MIN_VALUE, Long.MAX_VALUE, false); reportStats(stats); } catch (RemoteException e) { Log.w(LOG_TAG, "Failed to fetch network stats."); + } finally { + TrafficStats.closeQuietly(session); } } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java index 5e2a9fd..b7d2c26 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java @@ -141,7 +141,7 @@ public class FsUtils { } else if (!path.startsWith(HTTP_LOCAL_TESTS_PREFIX) && !path.startsWith(HTTP_MEDIA_TESTS_PREFIX) && !path.startsWith(HTTP_WML_TESTS_PREFIX)) { - url = "http://127.0.0.1:18000/" + path.substring(HTTP_TESTS_PREFIX.length()); + url = "http://127.0.0.1:8000/" + path.substring(HTTP_TESTS_PREFIX.length()); } else { url = "file://" + path; } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java index 3ba3488..fb2a1f4 100755 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java @@ -58,27 +58,9 @@ public class LayoutTestsAutoRunner extends InstrumentationTestRunner { } } - String delay_str = (String) icicle.get("delay"); - if(delay_str != null) { - try { - this.mDelay = Integer.parseInt(delay_str); - } catch (Exception e) { - } - } - String r = icicle.getString("rebaseline"); this.mRebaseline = (r != null && r.toLowerCase().equals("true")); - String logtime = icicle.getString("logtime"); - this.mLogtime = (logtime != null - && logtime.toLowerCase().equals("true")); - - String drawTime = icicle.getString("drawtime"); - this.mGetDrawTime = (drawTime != null - && drawTime.toLowerCase().equals("true")); - - mSaveImagePath = icicle.getString("saveimage"); - mJsEngine = icicle.getString("jsengine"); mPageCyclerSuite = icicle.getString("suite"); @@ -92,11 +74,7 @@ public class LayoutTestsAutoRunner extends InstrumentationTestRunner { String mPageCyclerForwardHost; String mPageCyclerIteration; String mTestPath; - String mSaveImagePath; - int mTimeoutInMillis; - int mDelay; + int mTimeoutInMillis = 0; boolean mRebaseline; - boolean mLogtime; - boolean mGetDrawTime; String mJsEngine; } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java index 7ac0665..3fe4e70 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java @@ -314,6 +314,10 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh public void timedOut(String url) { Log.v(LOGTAG, "layout timeout: " + url); } + + @Override + public void dumpResult(String webViewDump) { + } }); String resultFile = getResultFile(test); diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java index d883a32..4b86a0b 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java @@ -19,6 +19,7 @@ package com.android.dumprendertree; import com.android.dumprendertree.forwarder.AdbUtils; import com.android.dumprendertree.forwarder.ForwardServer; +import android.app.Activity; import android.app.Instrumentation; import android.content.Context; import android.content.Intent; @@ -106,8 +107,7 @@ public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShel freeMem(); // Run tests - runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis, - runner.mGetDrawTime, runner.mSaveImagePath); + runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis); getInstrumentation().runOnMainSync(new Runnable() { @@ -215,9 +215,9 @@ public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShel } // A convenient method to be called by another activity. - private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout, - boolean getDrawTime, String saveImagePath) { + private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) { activity.setCallback(new TestShellCallback() { + @Override public void finished() { synchronized (LoadTestsAutoTest.this) { mFinished = true; @@ -225,8 +225,29 @@ public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShel } } + @Override public void timedOut(String url) { } + + @Override + public void dumpResult(String webViewDump) { + String lines[] = webViewDump.split("\\r?\\n"); + for (String line : lines) { + line = line.trim(); + // parse for a line like this: + // totals: 9620.00 11947.00 10099.75 380.38 + // and return the 3rd number, which is mean + if (line.startsWith("totals:")) { + line = line.substring(7).trim(); // strip "totals:" + String[] numbers = line.split("\\s+"); + if (numbers.length == 4) { + Bundle b = new Bundle(); + b.putString("mean", numbers[2]); + getInstrumentation().sendStatus(Activity.RESULT_FIRST_USER, b); + } + } + } + } }); mFinished = false; @@ -236,9 +257,6 @@ public class LoadTestsAutoTest extends ActivityInstrumentationTestCase2<TestShel intent.putExtra(TestShellActivity.TEST_URL, url); intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout); intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT); - intent.putExtra(TestShellActivity.GET_DRAW_TIME, getDrawTime); - if (saveImagePath != null) - intent.putExtra(TestShellActivity.SAVE_IMAGE, saveImagePath); activity.startActivity(intent); // Wait until done. diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java deleted file mode 100644 index d146fc7..0000000 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dumprendertree; - -import android.app.Activity; -import android.content.Intent; -import android.os.Environment; -import android.os.Handler; -import android.os.Message; -import android.test.ActivityInstrumentationTestCase2; -import android.util.Log; - -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -public class ReliabilityTest extends ActivityInstrumentationTestCase2<ReliabilityTestActivity> { - - private static final String LOGTAG = "ReliabilityTest"; - private static final String PKG_NAME = "com.android.dumprendertree"; - private static final String EXTERNAL_DIR = - Environment.getExternalStorageDirectory().toString(); - private static final String TEST_LIST_FILE = EXTERNAL_DIR + - "/android/reliability_tests_list.txt"; - private static final String TEST_STATUS_FILE = EXTERNAL_DIR + - "/android/reliability_running_test.txt"; - private static final String TEST_TIMEOUT_FILE = EXTERNAL_DIR + - "/android/reliability_timeout_test.txt"; - private static final String TEST_LOAD_TIME_FILE = EXTERNAL_DIR + - "/android/reliability_load_time.txt"; - private static final String TEST_DONE = "#DONE"; - static final String RELIABILITY_TEST_RUNNER_FILES[] = { - "run_reliability_tests.py" - }; - - public ReliabilityTest() { - super(PKG_NAME, ReliabilityTestActivity.class); - } - - public void runReliabilityTest() throws Throwable { -// ReliabilityTestActivity activity = getActivity(); - LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation(); - - File testListFile = new File(TEST_LIST_FILE); - if(!testListFile.exists()) - throw new FileNotFoundException("test list file not found."); - - BufferedReader listReader = new BufferedReader( - new FileReader(testListFile)); - - //always try to resume first, hence cleaning up status will be the - //responsibility of driver scripts - String lastUrl = FsUtils.readTestStatus(TEST_STATUS_FILE); - if(lastUrl != null && !TEST_DONE.equals(lastUrl)) - fastForward(listReader, lastUrl); - - String url = null; - Handler handler = null; - boolean timeoutFlag = false; - long start, elapsed; - - Intent intent = new Intent(runner.getContext(), ReliabilityTestActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ReliabilityTestActivity activity = (ReliabilityTestActivity)runner.startActivitySync( - intent); - //read from BufferedReader instead of populating a list in advance, - //this will avoid excessive memory usage in case of a large list - while((url = listReader.readLine()) != null) { - url = url.trim(); - if(url.length() == 0) - continue; - start = System.currentTimeMillis(); - Log.v(LOGTAG, "Testing URL: " + url); - FsUtils.updateTestStatus(TEST_STATUS_FILE, url); - activity.reset(); - //use message to send new URL to avoid interacting with - //WebView in non-UI thread - handler = activity.getHandler(); - Message msg = handler.obtainMessage( - ReliabilityTestActivity.MSG_NAVIGATE, - runner.mTimeoutInMillis, runner.mDelay); - msg.getData().putString(ReliabilityTestActivity.MSG_NAV_URL, url); - msg.getData().putBoolean(ReliabilityTestActivity.MSG_NAV_LOGTIME, - runner.mLogtime); - handler.sendMessage(msg); - timeoutFlag = activity.waitUntilDone(); - elapsed = System.currentTimeMillis() - start; - if(elapsed < 1000) { - Log.w(LOGTAG, "Page load finished in " + elapsed - + "ms, too soon?"); - } else { - Log.v(LOGTAG, "Page load finished in " + elapsed + "ms"); - } - if(timeoutFlag) { - writeTimeoutFile(url); - } - if(runner.mLogtime) { - writeLoadTime(url, activity.getPageLoadTime()); - } - System.runFinalization(); - System.gc(); - System.gc(); - } - activity.finish(); - FsUtils.updateTestStatus(TEST_STATUS_FILE, TEST_DONE); -// activity.finish(); - listReader.close(); - } - - public void copyRunnerAssetsToCache() { - try { - String out_dir = getActivity().getApplicationContext() - .getCacheDir().getPath() + "/"; - - for( int i=0; i< RELIABILITY_TEST_RUNNER_FILES.length; i++) { - InputStream in = getActivity().getAssets().open( - RELIABILITY_TEST_RUNNER_FILES[i]); - OutputStream out = new FileOutputStream( - out_dir + RELIABILITY_TEST_RUNNER_FILES[i]); - - byte[] buf = new byte[2048]; - int len; - - while ((len = in.read(buf)) >= 0 ) { - out.write(buf, 0, len); - } - out.close(); - in.close(); - } - }catch (IOException e) { - Log.e(LOGTAG, "Cannot extract scripts for testing.", e); - } - } - - private void fastForward(BufferedReader testListReader, String lastUrl) { - //fastforward the BufferedReader to the position right after last url - if(lastUrl == null) - return; - - String line = null; - try { - while((line = testListReader.readLine()) != null) { - if(lastUrl.equals(line)) - return; - } - } catch (IOException ioe) { - Log.e(LOGTAG, "Error while reading test list.", ioe); - return; - } - } - - private void writeTimeoutFile(String s) { - //append to the file containing the list of timeout urls - try { - BufferedOutputStream bos = new BufferedOutputStream( - new FileOutputStream(TEST_TIMEOUT_FILE, true)); - bos.write(s.getBytes()); - bos.write('\n'); - bos.close(); - } catch (Exception e) { - Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE, e); - } - } - - private void writeLoadTime(String s, long time) { - //append to the file containing the list of timeout urls - try { - BufferedOutputStream bos = new BufferedOutputStream( - new FileOutputStream(TEST_LOAD_TIME_FILE, true)); - bos.write((s + '|' + time + '\n').getBytes()); - bos.close(); - } catch (Exception e) { - Log.e(LOGTAG, "Cannot update file " + TEST_LOAD_TIME_FILE, e); - } - } -} diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java index c0ba8cf..d151d9e 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java @@ -22,12 +22,9 @@ import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.content.DialogInterface.OnClickListener; +import android.content.Intent; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Bitmap.CompressFormat; -import android.graphics.Bitmap.Config; import android.net.http.SslError; import android.os.Bundle; import android.os.Environment; @@ -36,7 +33,6 @@ import android.os.Message; import android.util.Log; import android.view.ViewGroup; import android.view.Window; -import android.webkit.CookieManager; import android.webkit.ConsoleMessage; import android.webkit.CookieManager; import android.webkit.GeolocationPermissions; @@ -46,8 +42,10 @@ import android.webkit.JsResult; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebSettings; +import android.webkit.WebSettingsClassic; import android.webkit.WebStorage; import android.webkit.WebView; +import android.webkit.WebViewClassic; import android.webkit.WebViewClient; import android.widget.LinearLayout; @@ -113,10 +111,10 @@ public class TestShellActivity extends Activity implements LayoutTestController case DUMP_AS_TEXT: callback.arg1 = mDumpTopFrameAsText ? 1 : 0; callback.arg2 = mDumpChildFramesAsText ? 1 : 0; - mWebView.documentAsText(callback); + mWebViewClassic.documentAsText(callback); break; case EXT_REPR: - mWebView.externalRepresentation(callback); + mWebViewClassic.externalRepresentation(callback); break; default: finished(); @@ -145,6 +143,7 @@ public class TestShellActivity extends Activity implements LayoutTestController CookieManager.setAcceptFileSchemeCookies(true); mWebView = new WebView(this); + mWebViewClassic = WebViewClassic.fromWebView(mWebView); mEventSender = new WebViewEventSender(mWebView); mCallbackProxy = new CallbackProxy(mEventSender, this); @@ -159,7 +158,7 @@ public class TestShellActivity extends Activity implements LayoutTestController // Expose window.gc function to JavaScript. JSC build exposes // this function by default, but V8 requires the flag to turn it on. // WebView::setJsFlags is noop in JSC build. - mWebView.setJsFlags("--expose_gc"); + mWebViewClassic.setJsFlags("--expose_gc"); mHandler = new AsyncHandler(); @@ -169,7 +168,7 @@ public class TestShellActivity extends Activity implements LayoutTestController } // This is asynchronous, but it gets processed by WebCore before it starts loading pages. - mWebView.useMockDeviceOrientation(); + mWebViewClassic.useMockDeviceOrientation(); } @Override @@ -198,8 +197,6 @@ public class TestShellActivity extends Activity implements LayoutTestController mResultFile = intent.getStringExtra(RESULT_FILE); mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0); - mGetDrawtime = intent.getBooleanExtra(GET_DRAW_TIME, false); - mSaveImagePath = intent.getStringExtra(SAVE_IMAGE); mStopOnRefError = intent.getBooleanExtra(STOP_ON_REF_ERROR, false); setTitle("Test " + mCurrentTestNumber + " of " + mTotalTestCount); float ratio = (float)mCurrentTestNumber / mTotalTestCount; @@ -291,6 +288,7 @@ public class TestShellActivity extends Activity implements LayoutTestController super.onDestroy(); mWebView.destroy(); mWebView = null; + mWebViewClassic = null; } @Override @@ -308,6 +306,10 @@ public class TestShellActivity extends Activity implements LayoutTestController return; } + if (mCallback != null) { + mCallback.dumpResult(webkitData); + } + try { File parentDir = new File(mResultFile).getParentFile(); if (!parentDir.exists()) { @@ -532,8 +534,8 @@ public class TestShellActivity extends Activity implements LayoutTestController public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha, boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) { - mWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta, - canProvideGamma, gamma); + WebViewClassic.fromWebView(mWebView).setMockDeviceOrientation(canProvideAlpha, alpha, + canProvideBeta, beta, canProvideGamma, gamma); } public void overridePreference(String key, boolean value) { @@ -542,10 +544,10 @@ public class TestShellActivity extends Activity implements LayoutTestController // WebView for the main frame. EventSender suffers from the same // problem. if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) { - mWebView.getSettings().setAppCacheEnabled(value); + mWebViewClassic.getSettings().setAppCacheEnabled(value); } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) { // Cache the maximum possible number of pages. - mWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE); + mWebViewClassic.getSettings().setPageCacheCapacity(Integer.MAX_VALUE); } else { Log.w(LOGTAG, "LayoutTestController.overridePreference(): " + "Unsupported preference '" + key + "'"); @@ -553,7 +555,7 @@ public class TestShellActivity extends Activity implements LayoutTestController } public void setXSSAuditorEnabled (boolean flag) { - mWebView.getSettings().setXSSAuditorEnabled(flag); + mWebViewClassic.getSettings().setXSSAuditorEnabled(flag); } private final WebViewClient mViewClient = new WebViewClient(){ @@ -561,18 +563,6 @@ public class TestShellActivity extends Activity implements LayoutTestController public void onPageFinished(WebView view, String url) { Log.v(LOGTAG, "onPageFinished, url=" + url); mPageFinished = true; - // get page draw time - if (FsUtils.isTestPageUrl(url)) { - if (mGetDrawtime) { - long[] times = new long[DRAW_RUNS]; - times = getDrawWebViewTime(mWebView, DRAW_RUNS); - FsUtils.writeDrawTime(DRAW_TIME_LOG, url, times); - } - if (mSaveImagePath != null) { - String name = FsUtils.getLastSegmentInPath(url); - drawPageToFile(mSaveImagePath + "/" + name + ".png", mWebView); - } - } // Calling finished() will check if we've met all the conditions for completing // this test and move to the next one if we are ready. Otherwise we ask WebCore to @@ -827,47 +817,12 @@ public class TestShellActivity extends Activity implements LayoutTestController mEventSender.clearTouchMetaState(); mPageFinished = false; mDumpWebKitData = false; - mGetDrawtime = false; - mSaveImagePath = null; setDefaultWebSettings(mWebView); mIsGeolocationPermissionSet = false; mPendingGeolocationPermissionCallbacks = null; CookieManager.getInstance().removeAllCookie(); } - private long[] getDrawWebViewTime(WebView view, int count) { - if (count == 0) - return null; - long[] ret = new long[count]; - long start; - Canvas canvas = new Canvas(); - Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888); - canvas.setBitmap(bitmap); - for (int i = 0; i < count; i++) { - start = System.currentTimeMillis(); - view.draw(canvas); - ret[i] = System.currentTimeMillis() - start; - } - return ret; - } - - private void drawPageToFile(String fileName, WebView view) { - Canvas canvas = new Canvas(); - Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(), - Config.ARGB_8888); - canvas.setBitmap(bitmap); - view.drawPage(canvas); - try { - FileOutputStream fos = new FileOutputStream(fileName); - if(!bitmap.compress(CompressFormat.PNG, 90, fos)) { - Log.w(LOGTAG, "Failed to compress and save image."); - } - } catch (IOException ioe) { - Log.e(LOGTAG, "", ioe); - } - bitmap.recycle(); - } - private boolean canMoveToNextTest() { return (mDumpWebKitData && mPageFinished && !mWaitUntilDone) || mTimedOut; } @@ -886,11 +841,11 @@ public class TestShellActivity extends Activity implements LayoutTestController // single event rather than a stream of events (like what would generally happen in // a real use of touch events in a WebView) and so if the WebView drops the event, // the test will fail as the test expects one callback for every touch it synthesizes. - webview.setTouchInterval(-1); + WebViewClassic.fromWebView(webview).setTouchInterval(-1); } public void setDefaultWebSettings(WebView webview) { - WebSettings settings = webview.getSettings(); + WebSettingsClassic settings = WebViewClassic.fromWebView(webview).getSettings(); settings.setAppCacheEnabled(true); settings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); settings.setAppCacheMaxSize(Long.MAX_VALUE); @@ -904,11 +859,10 @@ public class TestShellActivity extends Activity implements LayoutTestController settings.setWorkersEnabled(false); settings.setXSSAuditorEnabled(false); settings.setPageCacheCapacity(0); - // this enables cpu upload path (as opposed to gpu upload path) - // and it's only meant to be a temporary workaround! - settings.setProperty("enable_cpu_upload_path", "true"); + settings.setProperty("use_minimal_memory", "false"); } + private WebViewClassic mWebViewClassic; private WebView mWebView; private WebViewEventSender mEventSender; private AsyncHandler mHandler; @@ -920,9 +874,7 @@ public class TestShellActivity extends Activity implements LayoutTestController private String mResultFile; private int mTimeoutInMillis; private String mUiAutoTestPath; - private String mSaveImagePath; private BufferedReader mTestListReader; - private boolean mGetDrawtime; private int mTotalTestCount; private int mCurrentTestNumber; private boolean mStopOnRefError; diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java index 55bf947..5220d57 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java @@ -18,5 +18,6 @@ package com.android.dumprendertree; public interface TestShellCallback { public void finished(); + public void dumpResult(String webViewDump); public void timedOut(String url); } diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java index 7a277d7..25dd04fd 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java @@ -26,7 +26,7 @@ import android.util.Log; public class ForwardService { - private ForwardServer fs18000, fs8080, fs8443; + private ForwardServer fs8000, fs8080, fs8443; private static ForwardService inst; @@ -40,7 +40,7 @@ public class ForwardService { private ForwardService() { int addr = getForwardHostAddr(); if (addr != -1) { - fs18000 = new ForwardServer(18000, addr, 8000); + fs8000 = new ForwardServer(8000, addr, 8000); fs8080 = new ForwardServer(8080, addr, 8080); fs8443 = new ForwardServer(8443, addr, 8443); } @@ -55,8 +55,8 @@ public class ForwardService { public void startForwardService() { try { - if (fs18000 != null) - fs18000.start(); + if (fs8000 != null) + fs8000.start(); if (fs8080 != null) fs8080.start(); if (fs8443 != null) @@ -68,9 +68,9 @@ public class ForwardService { } public void stopForwardService() { - if (fs18000 != null) { - fs18000.stop(); - fs18000 = null; + if (fs8000 != null) { + fs8000.stop(); + fs8000 = null; } if (fs8080 != null) { fs8080.stop(); diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java index f59da37..fc22472 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java @@ -41,9 +41,11 @@ import android.webkit.JsResult; import android.webkit.SslErrorHandler; import android.webkit.WebChromeClient; import android.webkit.WebSettings; +import android.webkit.WebSettingsClassic; import android.webkit.WebStorage; import android.webkit.WebStorage.QuotaUpdater; import android.webkit.WebView; +import android.webkit.WebViewClassic; import android.webkit.WebViewClient; import java.lang.Thread.UncaughtExceptionHandler; @@ -369,11 +371,12 @@ public class LayoutTestsExecutor extends Activity { * a real use of touch events in a WebView) and so if the WebView drops the event, * the test will fail as the test expects one callback for every touch it synthesizes. */ - webView.setTouchInterval(-1); + WebViewClassic webViewClassic = WebViewClassic.fromWebView(webView); + webViewClassic.setTouchInterval(-1); - webView.clearCache(true); + webViewClassic.clearCache(true); - WebSettings webViewSettings = webView.getSettings(); + WebSettingsClassic webViewSettings = webViewClassic.getSettings(); webViewSettings.setAppCacheEnabled(true); webViewSettings.setAppCachePath(getApplicationContext().getCacheDir().getPath()); // Use of larger values causes unexplained AppCache database corruption. @@ -391,7 +394,7 @@ public class LayoutTestsExecutor extends Activity { webViewSettings.setPageCacheCapacity(0); // This is asynchronous, but it gets processed by WebCore before it starts loading pages. - mCurrentWebView.useMockDeviceOrientation(); + WebViewClassic.fromWebView(mCurrentWebView).useMockDeviceOrientation(); // Must do this after setting the AppCache path. WebStorage.getInstance().deleteAllData(); @@ -625,10 +628,12 @@ public class LayoutTestsExecutor extends Activity { String key = msg.getData().getString("key"); boolean value = msg.getData().getBoolean("value"); if (WEBKIT_OFFLINE_WEB_APPLICATION_CACHE_ENABLED.equals(key)) { - mCurrentWebView.getSettings().setAppCacheEnabled(value); + WebViewClassic.fromWebView(mCurrentWebView).getSettings(). + setAppCacheEnabled(value); } else if (WEBKIT_USES_PAGE_CACHE_PREFERENCE_KEY.equals(key)) { // Cache the maximum possible number of pages. - mCurrentWebView.getSettings().setPageCacheCapacity(Integer.MAX_VALUE); + WebViewClassic.fromWebView(mCurrentWebView).getSettings(). + setPageCacheCapacity(Integer.MAX_VALUE); } else { Log.w(LOG_TAG, "LayoutTestController.overridePreference(): " + "Unsupported preference '" + key + "'"); @@ -656,7 +661,8 @@ public class LayoutTestsExecutor extends Activity { break; case MSG_SET_XSS_AUDITOR_ENABLED: - mCurrentWebView.getSettings().setXSSAuditorEnabled(msg.arg1 == 1); + WebViewClassic.fromWebView(mCurrentWebView).getSettings(). + setXSSAuditorEnabled(msg.arg1 == 1); break; case MSG_WAIT_UNTIL_DONE: @@ -728,8 +734,8 @@ public class LayoutTestsExecutor extends Activity { Log.i(LOG_TAG, mCurrentTestRelativePath + ": setMockDeviceOrientation(" + canProvideAlpha + ", " + alpha + ", " + canProvideBeta + ", " + beta + ", " + canProvideGamma + ", " + gamma + ")"); - mCurrentWebView.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta, - canProvideGamma, gamma); + WebViewClassic.fromWebView(mCurrentWebView).setMockDeviceOrientation(canProvideAlpha, + alpha, canProvideBeta, beta, canProvideGamma, gamma); } public void setXSSAuditorEnabled(boolean flag) { diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java index 3d2b98b..fd1c0ad 100644 --- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java +++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java @@ -20,6 +20,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.webkit.WebView; +import android.webkit.WebViewClassic; import name.fraser.neil.plaintext.diff_match_patch; @@ -233,7 +234,7 @@ public class TextResult extends AbstractResult { */ msg.arg1 = 1; msg.arg2 = mDumpChildFramesAsText ? 1 : 0; - webview.documentAsText(msg); + WebViewClassic.fromWebView(webview).documentAsText(msg); } @Override diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 929b103..3775f9f 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -30,6 +30,35 @@ android:label="HwUi" android:hardwareAccelerated="true"> + <meta-data android:name="android.graphics.renderThread" android:value="true" /> + + <activity + android:name="PaintDrawFilterActivity" + android:label="_DrawFilter"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name="DatePickerActivity" + android:label="_DatePicker"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name="ClipRegionActivity" + android:label="_ClipRegion"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name="DisplayListLayersActivity" android:label="__DisplayListLayers"> @@ -38,6 +67,15 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + + <activity + android:name="MatrixActivity" + android:label="_Matrix"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> <activity android:name="TextFadeActivity" @@ -466,6 +504,16 @@ </activity> <activity + android:name="PosTextActivity" + android:label="_PosText" + android:theme="@android:style/Theme.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="ListActivity" android:label="__List"> <intent-filter> @@ -529,6 +577,24 @@ </activity> <activity + android:name="TextOnPathActivity" + android:label="_TextOnPath"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name="PathsCacheActivity" + android:label="_PathsCache"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="PointsActivity" android:label="_Points"> <intent-filter> @@ -581,7 +647,6 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <activity android:name="StackActivity" @@ -592,5 +657,23 @@ </intent-filter> </activity> + <activity + android:name="TransformsAndAnimationsActivity" + android:label="_TransformAnim"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity + android:name="ViewPropertyAlphaActivity" + android:label="_ViewPropAlpha"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> </manifest> diff --git a/tests/HwAccelerationTest/res/layout/date_picker.xml b/tests/HwAccelerationTest/res/layout/date_picker.xml new file mode 100644 index 0000000..742a03b --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/date_picker.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** +** Copyright 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. +*/ +--> + +<!-- Layout of date picker--> + +<!-- The width of this container is manually set a little bigger than the one of the children + contained in it. This helps to prevent rounding errors when toggling the "Show year" option --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_gravity="center_horizontal" + android:layout_width="270dip" + android:layout_height="wrap_content"> + + <CheckBox + android:id="@+id/yearToggle" + android:text="Provide a year" + android:paddingTop="5dip" + android:paddingBottom="5dip" + android:textAppearance="?android:attr/textAppearanceLarge" + android:layout_gravity="center_horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + <!-- Warning: everything within the parent is removed and re-ordered depending + on the date format selected by the user. --> + <LinearLayout + android:id="@+id/parent" + android:orientation="horizontal" + android:layout_gravity="center_horizontal" + android:animateLayoutChanges="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <!-- Month --> + <NumberPicker + android:id="@+id/month" + android:layout_width="80dip" + android:layout_height="wrap_content" + android:layout_marginLeft="1dip" + android:layout_marginRight="1dip" + android:focusable="true" + android:focusableInTouchMode="true" + /> + + <!-- Day --> + <NumberPicker + android:id="@+id/day" + android:layout_width="80dip" + android:layout_height="wrap_content" + android:layout_marginLeft="1dip" + android:layout_marginRight="1dip" + android:focusable="true" + android:focusableInTouchMode="true" + /> + + <!-- Year --> + <NumberPicker + android:id="@+id/year" + android:layout_width="95dip" + android:layout_height="wrap_content" + android:layout_marginLeft="1dip" + android:layout_marginRight="1dip" + android:focusable="true" + android:focusableInTouchMode="true" + /> + </LinearLayout> +</LinearLayout> diff --git a/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml b/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml new file mode 100644 index 0000000..1595502 --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/transforms_and_animations.xml @@ -0,0 +1,145 @@ +<?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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <LinearLayout android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <CheckBox android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="None" + android:checked="true" + android:id="@+id/layersNoneCB"/> + + <CheckBox android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Hardware" + android:id="@+id/layersHwCB"/> + + <CheckBox android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Software" + android:id="@+id/layersSwCB"/> + + </LinearLayout> + + <LinearLayout android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1" + android:id="@+id/button1"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="2" + android:id="@+id/button2"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="3" + android:id="@+id/button3"/> + + </LinearLayout> + + <LinearLayout android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1a" + android:id="@+id/button1a"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="2a" + android:id="@+id/button2a"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="3a" + android:id="@+id/button3a"/> + + </LinearLayout> + + <LinearLayout android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="1b" + android:id="@+id/button1b"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="2b" + android:id="@+id/button2b"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="3b" + android:id="@+id/button3b"/> + + </LinearLayout> + + <view class="com.android.test.hwui.TransformsAndAnimationsActivity$MyLayout" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="4" + android:id="@+id/button4"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="5" + android:id="@+id/button5"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="6" + android:id="@+id/button6"/> + + </view> + + <LinearLayout android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="7" + android:id="@+id/button7"/> + + <Button android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="8" + android:id="@+id/button8"/> + + </LinearLayout> + +</LinearLayout> diff --git a/tests/HwAccelerationTest/res/layout/view_properties.xml b/tests/HwAccelerationTest/res/layout/view_properties.xml new file mode 100644 index 0000000..d7ed819 --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/view_properties.xml @@ -0,0 +1,81 @@ +<?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. +--> + +<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/container"> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Invalidate" + android:id="@+id/invalidateButton"/> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Button" + android:id="@+id/button"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Some text" + android:id="@+id/textview"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:id="@+id/spantext"/> + <EditText + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Edit text" + android:id="@+id/edittext"/> + <EditText + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Selected text" + android:id="@+id/selectedtext"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Some text" + android:background="#00ff00" + android:id="@+id/textviewbackground"/> + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/icon" + android:id="@+id/imageview"/> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:id="@+id/layout"> + <Button + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Button"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Some text"/> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Some text" + android:background="#00ff00"/> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/tests/HwAccelerationTest/res/values/strings.xml b/tests/HwAccelerationTest/res/values/strings.xml new file mode 100644 index 0000000..69e58aa --- /dev/null +++ b/tests/HwAccelerationTest/res/values/strings.xml @@ -0,0 +1,19 @@ +<?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. +--> + +<resources> + <string name="complex_string">"ตำแหน่งของตัวชี้"</string> +</resources> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java new file mode 100644 index 0000000..b2a508b --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Region; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class ClipRegionActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final RegionView view = new RegionView(this); + setContentView(view); + } + + public static class RegionView extends View { + public RegionView(Context c) { + super(c); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.save(); + canvas.clipRect(100.0f, 100.0f, getWidth() - 100.0f, getHeight() - 100.0f, + Region.Op.DIFFERENCE); + canvas.drawARGB(255, 255, 0, 0); + canvas.restore(); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java new file mode 100644 index 0000000..db247e3 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java @@ -0,0 +1,474 @@ +/* + * 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.test.hwui; + +import android.annotation.Widget; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.format.DateFormat; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.NumberPicker; + +import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +/** + * A view for selecting a month / year / day based on a calendar like layout. + * + * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-datepicker.html">Date Picker + * tutorial</a>.</p> + * + * For a dialog using this view, see {@link android.app.DatePickerDialog}. + */ +@Widget +public class DatePicker extends FrameLayout { + + private static final int DEFAULT_START_YEAR = 1900; + private static final int DEFAULT_END_YEAR = 2100; + + /* UI Components */ + private final CheckBox mYearToggle; + private final NumberPicker mDayPicker; + private final NumberPicker mMonthPicker; + private final NumberPicker mYearPicker; + + /** + * How we notify users the date has changed. + */ + private OnDateChangedListener mOnDateChangedListener; + + private int mDay; + private int mMonth; + private int mYear; + private boolean mYearOptional = true; + private boolean mHasYear; + + /** + * The callback used to indicate the user changes the date. + */ + public interface OnDateChangedListener { + + /** + * @param view The view associated with this listener. + * @param year The year that was set. + * @param monthOfYear The month that was set (0-11) for compatibility + * with {@link java.util.Calendar}. + * @param dayOfMonth The day of the month that was set. + */ + void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth); + } + + public DatePicker(Context context) { + this(context, null); + } + + public DatePicker(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + @SuppressWarnings("deprecation") + public DatePicker(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + ContextThemeWrapper themed = new ContextThemeWrapper(context, + com.android.internal.R.style.Theme_Holo_Light_Dialog_Alert); + LayoutInflater inflater = (LayoutInflater) themed.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(R.layout.date_picker, this, true); + + mDayPicker = (NumberPicker) findViewById(R.id.day); + mDayPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); + mDayPicker.setOnLongPressUpdateInterval(100); + mDayPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mDay = newVal; + notifyDateChanged(); + } + }); + mMonthPicker = (NumberPicker) findViewById(R.id.month); + mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER); + DateFormatSymbols dfs = new DateFormatSymbols(); + String[] months = dfs.getShortMonths(); + + /* + * If the user is in a locale where the month names are numeric, + * use just the number instead of the "month" character for + * consistency with the other fields. + */ + if (months[0].startsWith("1")) { + for (int i = 0; i < months.length; i++) { + months[i] = String.valueOf(i + 1); + } + mMonthPicker.setMinValue(1); + mMonthPicker.setMaxValue(12); + } else { + mMonthPicker.setMinValue(1); + mMonthPicker.setMaxValue(12); + mMonthPicker.setDisplayedValues(months); + } + + mMonthPicker.setOnLongPressUpdateInterval(200); + mMonthPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + + /* We display the month 1-12 but store it 0-11 so always + * subtract by one to ensure our internal state is always 0-11 + */ + mMonth = newVal - 1; + // Adjust max day of the month + adjustMaxDay(); + notifyDateChanged(); + updateDaySpinner(); + } + }); + mYearPicker = (NumberPicker) findViewById(R.id.year); + mYearPicker.setOnLongPressUpdateInterval(100); + mYearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + mYear = newVal; + // Adjust max day for leap years if needed + adjustMaxDay(); + notifyDateChanged(); + updateDaySpinner(); + } + }); + + mYearToggle = (CheckBox) findViewById(R.id.yearToggle); + mYearToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mHasYear = isChecked; + adjustMaxDay(); + notifyDateChanged(); + updateSpinners(); + } + }); + + // attributes + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.DatePicker); + + int mStartYear = + a.getInt(com.android.internal.R.styleable.DatePicker_startYear, DEFAULT_START_YEAR); + int mEndYear = + a.getInt(com.android.internal.R.styleable.DatePicker_endYear, DEFAULT_END_YEAR); + mYearPicker.setMinValue(mStartYear); + mYearPicker.setMaxValue(mEndYear); + + a.recycle(); + + // initialize to current date + Calendar cal = Calendar.getInstance(); + init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null); + + // re-order the number pickers to match the current date format + reorderPickers(months); + + if (!isEnabled()) { + setEnabled(false); + } + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + mDayPicker.setEnabled(enabled); + mMonthPicker.setEnabled(enabled); + mYearPicker.setEnabled(enabled); + } + + private void reorderPickers(String[] months) { + java.text.DateFormat format; + String order; + + /* + * If the user is in a locale where the medium date format is + * still numeric (Japanese and Czech, for example), respect + * the date format order setting. Otherwise, use the order + * that the locale says is appropriate for a spelled-out date. + */ + + if (months[0].startsWith("1")) { + format = DateFormat.getDateFormat(getContext()); + } else { + format = DateFormat.getMediumDateFormat(getContext()); + } + + if (format instanceof SimpleDateFormat) { + order = ((SimpleDateFormat) format).toPattern(); + } else { + // Shouldn't happen, but just in case. + order = new String(DateFormat.getDateFormatOrder(getContext())); + } + + /* Remove the 3 pickers from their parent and then add them back in the + * required order. + */ + LinearLayout parent = (LinearLayout) findViewById(R.id.parent); + parent.removeAllViews(); + + boolean quoted = false; + boolean didDay = false, didMonth = false, didYear = false; + + for (int i = 0; i < order.length(); i++) { + char c = order.charAt(i); + + if (c == '\'') { + quoted = !quoted; + } + + if (!quoted) { + if (c == DateFormat.DATE && !didDay) { + parent.addView(mDayPicker); + didDay = true; + } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) { + parent.addView(mMonthPicker); + didMonth = true; + } else if (c == DateFormat.YEAR && !didYear) { + parent.addView (mYearPicker); + didYear = true; + } + } + } + + // Shouldn't happen, but just in case. + if (!didMonth) { + parent.addView(mMonthPicker); + } + if (!didDay) { + parent.addView(mDayPicker); + } + if (!didYear) { + parent.addView(mYearPicker); + } + } + + public void updateDate(int year, int monthOfYear, int dayOfMonth) { + if (mYear != year || mMonth != monthOfYear || mDay != dayOfMonth) { + mYear = (mYearOptional && year == 0) ? getCurrentYear() : year; + mMonth = monthOfYear; + mDay = dayOfMonth; + updateSpinners(); + reorderPickers(new DateFormatSymbols().getShortMonths()); + notifyDateChanged(); + } + } + + private static int getCurrentYear() { + return Calendar.getInstance().get(Calendar.YEAR); + } + + private static class SavedState extends BaseSavedState { + + private final int mYear; + private final int mMonth; + private final int mDay; + private final boolean mHasYear; + private final boolean mYearOptional; + + /** + * Constructor called from {@link DatePicker#onSaveInstanceState()} + */ + private SavedState(Parcelable superState, int year, int month, int day, boolean hasYear, + boolean yearOptional) { + super(superState); + mYear = year; + mMonth = month; + mDay = day; + mHasYear = hasYear; + mYearOptional = yearOptional; + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + mYear = in.readInt(); + mMonth = in.readInt(); + mDay = in.readInt(); + mHasYear = in.readInt() != 0; + mYearOptional = in.readInt() != 0; + } + + public int getYear() { + return mYear; + } + + public int getMonth() { + return mMonth; + } + + public int getDay() { + return mDay; + } + + public boolean hasYear() { + return mHasYear; + } + + public boolean isYearOptional() { + return mYearOptional; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(mYear); + dest.writeInt(mMonth); + dest.writeInt(mDay); + dest.writeInt(mHasYear ? 1 : 0); + dest.writeInt(mYearOptional ? 1 : 0); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator<SavedState> CREATOR = + new Creator<SavedState>() { + + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + + /** + * Override so we are in complete control of save / restore for this widget. + */ + @Override + protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { + dispatchThawSelfOnly(container); + } + + @Override + protected Parcelable onSaveInstanceState() { + Parcelable superState = super.onSaveInstanceState(); + + return new SavedState(superState, mYear, mMonth, mDay, mHasYear, mYearOptional); + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + mYear = ss.getYear(); + mMonth = ss.getMonth(); + mDay = ss.getDay(); + mHasYear = ss.hasYear(); + mYearOptional = ss.isYearOptional(); + updateSpinners(); + } + + /** + * Initialize the state. + * @param year The initial year. + * @param monthOfYear The initial month. + * @param dayOfMonth The initial day of the month. + * @param onDateChangedListener How user is notified date is changed by user, can be null. + */ + public void init(int year, int monthOfYear, int dayOfMonth, + OnDateChangedListener onDateChangedListener) { + init(year, monthOfYear, dayOfMonth, false, onDateChangedListener); + } + + /** + * Initialize the state. + * @param year The initial year or 0 if no year has been specified + * @param monthOfYear The initial month. + * @param dayOfMonth The initial day of the month. + * @param yearOptional True if the user can toggle the year + * @param onDateChangedListener How user is notified date is changed by user, can be null. + */ + public void init(int year, int monthOfYear, int dayOfMonth, boolean yearOptional, + OnDateChangedListener onDateChangedListener) { + mYear = (yearOptional && year == 0) ? getCurrentYear() : year; + mMonth = monthOfYear; + mDay = dayOfMonth; + mYearOptional = yearOptional; + mHasYear = !yearOptional || (year != 0); + mOnDateChangedListener = onDateChangedListener; + updateSpinners(); + } + + private void updateSpinners() { + updateDaySpinner(); + mYearToggle.setChecked(mHasYear); + mYearToggle.setVisibility(mYearOptional ? View.VISIBLE : View.GONE); + mYearPicker.setValue(mYear); + mYearPicker.setVisibility(mHasYear ? View.VISIBLE : View.GONE); + + /* The month display uses 1-12 but our internal state stores it + * 0-11 so add one when setting the display. + */ + mMonthPicker.setValue(mMonth + 1); + } + + private void updateDaySpinner() { + Calendar cal = Calendar.getInstance(); + // if year was not set, use 2000 as it was a leap year + cal.set(mHasYear ? mYear : 2000, mMonth, 1); + int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH); + mDayPicker.setMinValue(1); + mDayPicker.setMaxValue(max); + mDayPicker.setValue(mDay); + } + + public int getYear() { + return (mYearOptional && !mHasYear) ? 0 : mYear; + } + + public int getMonth() { + return mMonth; + } + + public int getDayOfMonth() { + return mDay; + } + + private void adjustMaxDay(){ + Calendar cal = Calendar.getInstance(); + // if year was not set, use 2000 as it was a leap year + cal.set(Calendar.YEAR, mHasYear ? mYear : 2000); + cal.set(Calendar.MONTH, mMonth); + int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH); + if (mDay > max) { + mDay = max; + } + } + + private void notifyDateChanged() { + if (mOnDateChangedListener != null) { + int year = (mYearOptional && !mHasYear) ? 0 : mYear; + mOnDateChangedListener.onDateChanged(DatePicker.this, year, mMonth, mDay); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java new file mode 100644 index 0000000..5482ee2 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; + +@SuppressWarnings({"UnusedDeclaration"}) +public class DatePickerActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + DatePicker picker = new DatePicker(this); + picker.init(2012, 3, 3, true, new DatePicker.OnDateChangedListener() { + @Override + public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) { + } + }); + setContentView(picker); + getWindow().setBackgroundDrawable(new ColorDrawable(0xffffffff)); + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MatrixActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MatrixActivity.java new file mode 100644 index 0000000..1906b9d --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MatrixActivity.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class MatrixActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(new MatrixView(this)); + } + + static class MatrixView extends View { + MatrixView(Context c) { + super(c); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.drawRGB(255, 255, 255); + + Log.d("Matrix", "m1=" + canvas.getMatrix()); + + canvas.save(); + canvas.translate(10.0f, 10.0f); + Log.d("Matrix", "m2=" + canvas.getMatrix()); + canvas.translate(20.0f, 20.0f); + Log.d("Matrix", "m3=" + canvas.getMatrix()); + canvas.restore(); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PaintDrawFilterActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PaintDrawFilterActivity.java new file mode 100644 index 0000000..8523272 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PaintDrawFilterActivity.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class PaintDrawFilterActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(new CustomTextView(this)); + } + + static class CustomTextView extends View { + private final Paint mMediumPaint; + private final PaintFlagsDrawFilter mDrawFilter; + + CustomTextView(Context c) { + super(c); + + mMediumPaint = new Paint(); + mMediumPaint.setAntiAlias(true); + mMediumPaint.setColor(0xff000000); + mMediumPaint.setFakeBoldText(true); + mMediumPaint.setTextSize(24.0f); + + mDrawFilter = new PaintFlagsDrawFilter( + Paint.FAKE_BOLD_TEXT_FLAG, Paint.UNDERLINE_TEXT_FLAG); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.drawRGB(255, 255, 255); + + canvas.setDrawFilter(null); + canvas.drawText("Hello OpenGL renderer!", 100, 120, mMediumPaint); + canvas.setDrawFilter(mDrawFilter); + canvas.drawText("Hello OpenGL renderer!", 100, 220, mMediumPaint); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java new file mode 100644 index 0000000..9ab2a86 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.os.Bundle; +import android.util.Log; +import android.view.View; + +import java.util.ArrayList; +import java.util.Random; + +@SuppressWarnings({"UnusedDeclaration"}) +public class PathsCacheActivity extends Activity { + private Path mPath; + + private final Random mRandom = new Random(); + private final ArrayList<Path> mPathList = new ArrayList<Path>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPath = makePath(); + + final PathsView view = new PathsView(this); + setContentView(view); + } + + private Path makePath() { + Path path = new Path(); + buildPath(path); + return path; + } + + private void buildPath(Path path) { + path.moveTo(0.0f, 0.0f); + path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f); + path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f); + path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f); + } + + public class PathsView extends View { + private final Paint mMediumPaint; + + public PathsView(Context c) { + super(c); + + mMediumPaint = new Paint(); + mMediumPaint.setAntiAlias(true); + mMediumPaint.setColor(0xe00000ff); + mMediumPaint.setStrokeWidth(10.0f); + mMediumPaint.setStyle(Paint.Style.STROKE); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + Log.d("OpenGLRenderer", "Start frame"); + + canvas.drawARGB(255, 255, 255, 255); + + canvas.save(); + canvas.translate(550.0f, 60.0f); + canvas.drawPath(mPath, mMediumPaint); + + mPath.reset(); + buildPath(mPath); + + canvas.translate(30.0f, 30.0f); + canvas.drawPath(mPath, mMediumPaint); + canvas.drawPath(mPath, mMediumPaint); + + canvas.restore(); + + for (int i = 0; i < mRandom.nextInt(20); i++) { + Path path = makePath(); + int r = mRandom.nextInt(10); + if (r == 5 || r == 3) { + mPathList.add(path); + } + + canvas.save(); + canvas.translate(450.0f + mRandom.nextInt(200), mRandom.nextInt(200)); + canvas.drawPath(path, mMediumPaint); + canvas.restore(); + } + + int r = mRandom.nextInt(100); + if (r == 50) { + mPathList.clear(); + } + + invalidate(); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PosTextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PosTextActivity.java new file mode 100644 index 0000000..1c868d2 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PosTextActivity.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class PosTextActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(new CustomTextView(this)); + } + + static class CustomTextView extends View { + private final Paint mLargePaint; + private final String mText; + private final float[] mPos; + + CustomTextView(Context c) { + super(c); + + mText = c.getResources().getString(R.string.complex_string); + mPos = new float[mText.length() * 2]; + for (int i = 0; i < mPos.length; i += 2) { + mPos[i] = i * 30.0f; + mPos[i + 1] = i * 10.0f; + } + + mLargePaint = new Paint(); + mLargePaint.setAntiAlias(true); + mLargePaint.setTextSize(36.0f); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.drawRGB(255, 255, 255); + + canvas.save(); + + canvas.drawLine(100.0f, 0.0f, 100.0f, getHeight(), mLargePaint); + + canvas.translate(100.0f, 100.0f); + mLargePaint.setTextAlign(Paint.Align.LEFT); + canvas.drawPosText(mText, mPos, mLargePaint); + + canvas.translate(0.0f, 50.0f); + mLargePaint.setTextAlign(Paint.Align.CENTER); + canvas.drawPosText(mText, mPos, mLargePaint); + + canvas.translate(0.0f, 50.0f); + mLargePaint.setTextAlign(Paint.Align.RIGHT); + canvas.drawPosText(mText, mPos, mLargePaint); + + canvas.restore(); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java index 4037a69..0a868fa 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java @@ -21,6 +21,7 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; +import android.text.TextPaint; import android.view.View; @SuppressWarnings({"UnusedDeclaration"}) @@ -39,6 +40,7 @@ public class TextActivity extends Activity { private final Paint mScaledPaint; private final Paint mSkewPaint; private final Paint mHugePaint; + private final TextPaint mEventPaint; CustomTextView(Context c) { super(c); @@ -70,6 +72,11 @@ public class TextActivity extends Activity { mHugePaint.setAntiAlias(true); mHugePaint.setColor(0xff000000); mHugePaint.setTextSize(300f); + + mEventPaint = new TextPaint(); + mEventPaint.setFakeBoldText(true); + mEventPaint.setAntiAlias(true); + mEventPaint.setTextSize(14); } @Override @@ -77,6 +84,8 @@ public class TextActivity extends Activity { super.onDraw(canvas); canvas.drawRGB(255, 255, 255); + canvas.drawText("Hello OpenGL renderer!", 300, 20, mEventPaint); + mMediumPaint.setStyle(Paint.Style.FILL_AND_STROKE); mMediumPaint.setStrokeWidth(2.0f); canvas.drawText("Hello OpenGL renderer!", 100, 20, mMediumPaint); diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java new file mode 100644 index 0000000..9849e3c --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2010 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.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PathMeasure; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class TextOnPathActivity extends Activity { + private Path mPath; + private Path mStraightPath; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mPath = makePath(); + mStraightPath = makeStraightPath(); + + final TextOnPathView view = new TextOnPathView(this); + setContentView(view); + } + + private Path makePath() { + Path path = new Path(); + buildPath(path); + return path; + } + + private void buildPath(Path path) { + path.moveTo(0.0f, 0.0f); + path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f); + path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f); + path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f); + } + + private Path makeStraightPath() { + Path path = new Path(); + buildStraightPath(path); + return path; + } + + private void buildStraightPath(Path path) { + path.moveTo(0.0f, 0.0f); + path.lineTo(400.0f, 0.0f); + } + + public class TextOnPathView extends View { + private static final String TEST_STRING = "Hello OpenGL renderer, text on path! "; + + private final Paint mPaint; + private final Paint mPathPaint; + private final String mText; + private final PathMeasure mMeasure; + private final float mLength; + private final float[] mLines; + private final float[] mPos; + private final float[] mTan; + + public TextOnPathView(Context c) { + super(c); + + mPaint = new Paint(); + mPaint.setAntiAlias(true); + mPaint.setColor(0xff000000); + + mPathPaint = new Paint(); + mPathPaint.setAntiAlias(true); + mPathPaint.setStyle(Paint.Style.STROKE); + mPathPaint.setColor(0xff000099); + + StringBuilder builder = new StringBuilder(TEST_STRING.length() * 2); + for (int i = 0; i < 2; i++) { + builder.append(TEST_STRING); + } + mText = builder.toString(); + + mMeasure = new PathMeasure(mPath, false); + mLength = mMeasure.getLength(); + + mLines = new float[100 * 4]; + mPos = new float[2]; + mTan = new float[2]; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.drawARGB(255, 255, 255, 255); + + canvas.save(); + canvas.translate(400.0f, 350.0f); + mPaint.setTextAlign(Paint.Align.LEFT); + canvas.drawTextOnPath(mText + mText, mPath, 0.0f, 0.0f, mPaint); + canvas.drawPath(mPath, mPathPaint); + + for (int i = 0; i < 100; i++) { + mMeasure.getPosTan(i * mLength / 100.0f, mPos, mTan); + mLines[i * 4 ] = mPos[0]; + mLines[i * 4 + 1] = mPos[1]; + mLines[i * 4 + 2] = mPos[0] + mTan[1] * 15; + mLines[i * 4 + 3] = mPos[1] - mTan[0] * 15; + } + canvas.drawLines(mLines, mPathPaint); + + canvas.translate(200.0f, 0.0f); + canvas.drawTextOnPath(mText + mText, mStraightPath, 0.0f, 0.0f, mPaint); + canvas.drawPath(mStraightPath, mPathPaint); + + canvas.restore(); + + canvas.save(); + canvas.translate(150.0f, 60.0f); + canvas.drawTextOnPath(mText, mPath, 0.0f, 10.0f, mPaint); + mMeasure.getPosTan(5.0f, mPos, mTan); + canvas.drawLine(mPos[0], mPos[1], mPos[0] + mTan[1] * 10, mPos[1] - mTan[0] * 10, + mPathPaint); + canvas.drawPath(mPath, mPathPaint); + + canvas.translate(250.0f, 0.0f); + mPaint.setTextAlign(Paint.Align.CENTER); + canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint); + canvas.drawPath(mPath, mPathPaint); + + canvas.translate(250.0f, 0.0f); + mPaint.setTextAlign(Paint.Align.RIGHT); + canvas.drawTextOnPath(mText, mPath, 0.0f, 0.0f, mPaint); + canvas.drawPath(mPath, mPathPaint); + canvas.restore(); + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java new file mode 100644 index 0000000..684d179 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java @@ -0,0 +1,201 @@ +/* + * 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.test.hwui; + +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.Transformation; +import android.view.animation.TranslateAnimation; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.LinearLayout; + +public class TransformsAndAnimationsActivity extends Activity { + Button button1; + Button button2; + Button button3; + Button button1a; + Button button2a; + Button button3a; + Button button1b; + Button button2b; + Button button3b; + Button button4; + Button button5; + Button button6; + Button button7; + Button button8; + CheckBox layersNoneCB; + CheckBox layersHardwareCB; + CheckBox layersSoftwareCB; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.transforms_and_animations); + + button1 = (Button) findViewById(R.id.button1); + button2 = (Button) findViewById(R.id.button2); + button3 = (Button) findViewById(R.id.button3); + button1a = (Button) findViewById(R.id.button1a); + button2a = (Button) findViewById(R.id.button2a); + button3a = (Button) findViewById(R.id.button3a); + button1b = (Button) findViewById(R.id.button1b); + button2b = (Button) findViewById(R.id.button2b); + button3b = (Button) findViewById(R.id.button3b); + button4 = (Button) findViewById(R.id.button4); + button5 = (Button) findViewById(R.id.button5); + button6 = (Button) findViewById(R.id.button6); + button7 = (Button) findViewById(R.id.button7); + button8 = (Button) findViewById(R.id.button8); + layersNoneCB = (CheckBox) findViewById(R.id.layersNoneCB); + layersHardwareCB = (CheckBox) findViewById(R.id.layersHwCB); + layersSoftwareCB = (CheckBox) findViewById(R.id.layersSwCB); + + layersNoneCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + setLayerType(View.LAYER_TYPE_NONE); + layersHardwareCB.setChecked(false); + layersSoftwareCB.setChecked(false); + } + } + }); + + layersSoftwareCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + setLayerType(View.LAYER_TYPE_SOFTWARE); + layersHardwareCB.setChecked(false); + layersNoneCB.setChecked(false); + } + } + }); + + layersHardwareCB.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + setLayerType(View.LAYER_TYPE_HARDWARE); + layersNoneCB.setChecked(false); + layersSoftwareCB.setChecked(false); + } + } + }); + + button1a.setAlpha(.5f); + button2a.setAlpha(.5f); + button3a.setAlpha(.5f); + button3.setTranslationX(50); + button7.setTranslationX(50); + button8.setTranslationX(50); + + final AlphaAnimation alphaAnim = new AlphaAnimation(1, 0); + alphaAnim.setDuration(1000); + alphaAnim.setRepeatCount(Animation.INFINITE); + alphaAnim.setRepeatMode(Animation.REVERSE); + + final TranslateAnimation transAnim = new TranslateAnimation(0, -50, 0, 0); + transAnim.setDuration(1000); + transAnim.setRepeatCount(Animation.INFINITE); + transAnim.setRepeatMode(Animation.REVERSE); + + getWindow().getDecorView().postDelayed(new Runnable() { + @Override + public void run() { + button1.startAnimation(alphaAnim); + button2.startAnimation(alphaAnim); + button3.startAnimation(alphaAnim); + + button1a.startAnimation(alphaAnim); + button2a.startAnimation(alphaAnim); + button3a.startAnimation(alphaAnim); + + button1b.startAnimation(alphaAnim); + button2b.startAnimation(alphaAnim); + button3b.startAnimation(alphaAnim); + startAnimator(button1b); + startAnimator(button2b); + startAnimator(button3b); + + button7.startAnimation(transAnim); + button8.startAnimation(transAnim); + } + }, 2000); + } + + private void setLayerType(int layerType) { + button1.setLayerType(layerType, null); + button2.setLayerType(layerType, null); + button3.setLayerType(layerType, null); + button1a.setLayerType(layerType, null); + button2a.setLayerType(layerType, null); + button3a.setLayerType(layerType, null); + button1b.setLayerType(layerType, null); + button2b.setLayerType(layerType, null); + button3b.setLayerType(layerType, null); + button4.setLayerType(layerType, null); + button5.setLayerType(layerType, null); + button6.setLayerType(layerType, null); + button7.setLayerType(layerType, null); + button8.setLayerType(layerType, null); + } + + private void startAnimator(View target) { + ObjectAnimator anim1b = ObjectAnimator.ofFloat(target, View.ALPHA, 0); + anim1b.setRepeatCount(ValueAnimator.INFINITE); + anim1b.setRepeatMode(ValueAnimator.REVERSE); + anim1b.setDuration(1000); + anim1b.start(); + } + + public static class MyLayout extends LinearLayout { + + public MyLayout(Context context) { + super(context); + setStaticTransformationsEnabled(true); + } + + public MyLayout(Context context, AttributeSet attrs) { + super(context, attrs); + setStaticTransformationsEnabled(true); + } + + public MyLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + setStaticTransformationsEnabled(true); + } + + @Override + protected boolean getChildStaticTransformation(View child, Transformation t) { + t.clear(); + t.setAlpha(.35f); + + return true; + } + } +} + diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java new file mode 100644 index 0000000..738801d --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java @@ -0,0 +1,145 @@ +/* + * 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.test.hwui; + +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; +import android.app.Activity; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.Bundle; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.BackgroundColorSpan; +import android.text.style.ForegroundColorSpan; +import android.text.style.ImageSpan; +import android.text.style.SuggestionSpan; +import android.text.style.UnderlineSpan; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class ViewPropertyAlphaActivity extends Activity { + + MyView myViewAlphaDefault, myViewAlphaHandled; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.view_properties); + + getWindow().getDecorView().postDelayed(new Runnable() { + @Override + public void run() { + startAnim(R.id.button); + startAnim(R.id.textview); + startAnim(R.id.spantext); + startAnim(R.id.edittext); + startAnim(R.id.selectedtext); + startAnim(R.id.textviewbackground); + startAnim(R.id.layout); + startAnim(R.id.imageview); + startAnim(myViewAlphaDefault); + startAnim(myViewAlphaHandled); + EditText selectedText = (EditText) findViewById(R.id.selectedtext); + selectedText.setSelection(3, 8); + } + }, 2000); + + Button invalidator = (Button) findViewById(R.id.invalidateButton); + invalidator.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + findViewById(R.id.textview).invalidate(); + findViewById(R.id.spantext).invalidate(); + } + }); + + TextView textView = (TextView) findViewById(R.id.spantext); + if (textView != null) { + SpannableStringBuilder text = + new SpannableStringBuilder("Now this is a short text message with spans"); + + text.setSpan(new BackgroundColorSpan(Color.RED), 0, 3, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + text.setSpan(new ForegroundColorSpan(Color.BLUE), 4, 9, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + text.setSpan(new SuggestionSpan(this, new String[]{"longer"}, 3), 11, 16, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + text.setSpan(new UnderlineSpan(), 17, 20, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + text.setSpan(new ImageSpan(this, R.drawable.icon), 21, 22, + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + + textView.setText(text); + } + + LinearLayout container = (LinearLayout) findViewById(R.id.container); + myViewAlphaDefault = new MyView(this, false); + myViewAlphaDefault.setLayoutParams(new LinearLayout.LayoutParams(75, 75)); + container.addView(myViewAlphaDefault); + myViewAlphaHandled = new MyView(this, true); + myViewAlphaHandled.setLayoutParams(new LinearLayout.LayoutParams(75, 75)); + container.addView(myViewAlphaHandled); + } + + private void startAnim(View target) { + ObjectAnimator anim = ObjectAnimator.ofFloat(target, View.ALPHA, 0); + anim.setRepeatCount(ValueAnimator.INFINITE); + anim.setRepeatMode(ValueAnimator.REVERSE); + anim.setDuration(1000); + anim.start(); + } + private void startAnim(int id) { + startAnim(findViewById(id)); + } + + private static class MyView extends View { + private int mMyAlpha = 255; + private boolean mHandleAlpha; + private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + private MyView(Context context, boolean handleAlpha) { + super(context); + mHandleAlpha = handleAlpha; + mPaint.setColor(Color.RED); + } + + @Override + protected void onDraw(Canvas canvas) { + if (mHandleAlpha) { + mPaint.setAlpha(mMyAlpha); + } + canvas.drawCircle(30, 30, 30, mPaint); + } + + @Override + protected boolean onSetAlpha(int alpha) { + if (mHandleAlpha) { + mMyAlpha = alpha; + return true; + } + return super.onSetAlpha(alpha); + } + } + +} diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java index f7abe8b..5446f66 100644 --- a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java +++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011-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. @@ -22,10 +22,10 @@ import android.graphics.BitmapFactory; import android.graphics.Bitmap; import android.renderscript.RenderScript; import android.renderscript.Allocation; +import android.util.Log; import android.widget.ImageView; public class ComputePerf extends Activity { - private LaunchTest mLT; private Mandelbrot mMandel; private RenderScript mRS; @@ -35,14 +35,28 @@ public class ComputePerf extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.main); + final int numTries = 100; + + long timesXLW = 0; + long timesXYW = 0; + mRS = RenderScript.create(this); mLT = new LaunchTest(mRS, getResources()); - mLT.run(); - mLT.run(); + mLT.XLW(); + mLT.XYW(); + for (int i = 0; i < numTries; i++) { + timesXLW += mLT.XLW(); + timesXYW += mLT.XYW(); + } + + timesXLW /= numTries; + timesXYW /= numTries; + + // XLW and XYW running times should match pretty closely + Log.v("ComputePerf", "xlw launch test " + timesXLW + "ms"); + Log.v("ComputePerf", "xyw launch test " + timesXYW + "ms"); mMandel = new Mandelbrot(mRS, getResources()); mMandel.run(); - } - } diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java index 0c29ce1..e2312ba 100644 --- a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java +++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011-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. @@ -19,7 +19,7 @@ package com.example.android.rs.computeperf; import android.content.res.Resources; import android.renderscript.*; -public class LaunchTest implements Runnable { +public class LaunchTest { private RenderScript mRS; private Allocation mAllocationX; private Allocation mAllocationXY; @@ -40,18 +40,19 @@ public class LaunchTest implements Runnable { mScript_xlw.bind_buf(mAllocationXY); } - public void run() { + public long XLW() { long t = java.lang.System.currentTimeMillis(); mScript_xlw.forEach_root(mAllocationX); mRS.finish(); t = java.lang.System.currentTimeMillis() - t; - android.util.Log.v("ComputePerf", "xlw launch test ms " + t); + return t; + } - t = java.lang.System.currentTimeMillis(); + public long XYW() { + long t = java.lang.System.currentTimeMillis(); mScript_xyw.forEach_root(mAllocationXY); mRS.finish(); t = java.lang.System.currentTimeMillis() - t; - android.util.Log.v("ComputePerf", "xyw launch test ms " + t); + return t; } - } diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs index a7987b3..0ffb0e5 100644 --- a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs +++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs @@ -25,13 +25,14 @@ void root(uchar4 *v_out, uint32_t x, uint32_t y) { p.y = -1.f + ((float)y / gDimY) * 2.f; float2 t = 0; + float2 t2 = t * t; int iteration = 0; - while((t.x*t.x + t.y*t.y < 4.f) && (iteration < gMaxIteration)) { - float2 t2 = t * t; + while((t2.x + t2.y < 4.f) && (iteration < gMaxIteration)) { float xtemp = t2.x - t2.y + p.x; t.y = 2 * t.x * t.y + p.y; t.x = xtemp; iteration++; + t2 = t * t; } if(iteration >= gMaxIteration) { diff --git a/tests/RenderScriptTests/Fountain_v11/Android.mk b/tests/RenderScriptTests/Fountain_v11/Android.mk new file mode 100644 index 0000000..e51115c --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/Android.mk @@ -0,0 +1,32 @@ +# +# 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. +# + +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) +#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript + +LOCAL_PACKAGE_NAME := Fountain_v11 +LOCAL_SDK_VERSION := 11 + +include $(BUILD_PACKAGE) + +endif diff --git a/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml b/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml new file mode 100644 index 0000000..fcb4faf --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.fountain_v11"> + <uses-sdk android:minSdkVersion="11" /> + <application + android:label="Fountain_v11" + android:icon="@drawable/test_pattern"> + <activity android:name="Fountain_v11"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/Fountain_v11/_index.html b/tests/RenderScriptTests/Fountain_v11/_index.html new file mode 100644 index 0000000..223242f --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/_index.html @@ -0,0 +1,5 @@ +<p>An example that renders many dots on the screen that follow a user's touch. The dots fall +to the bottom of the screen when the user releases the finger.</p> + + + diff --git a/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png b/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java new file mode 100644 index 0000000..e858100 --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fountain_v11; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + + +public class FountainRS { + public static final int PART_COUNT = 50000; + + public FountainRS() { + } + + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_fountain mScript; + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + + ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs); + pfb.setVaryingColor(true); + rs.bindProgramFragment(pfb.create()); + + ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);// + // Allocation.USAGE_GRAPHICS_VERTEX); + + Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); + smb.addVertexAllocation(points.getAllocation()); + smb.addIndexSetType(Mesh.Primitive.POINT); + Mesh sm = smb.create(); + + mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain); + mScript.set_partMesh(sm); + mScript.bind_point(points); + mRS.bindRootScript(mScript); + } + + boolean holdingColor[] = new boolean[10]; + public void newTouchPosition(float x, float y, float pressure, int id) { + if (id >= holdingColor.length) { + return; + } + int rate = (int)(pressure * pressure * 500.f); + if (rate > 500) { + rate = 500; + } + if (rate > 0) { + mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]); + holdingColor[id] = true; + } else { + holdingColor[id] = false; + } + + } +} diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java new file mode 100644 index 0000000..e82376c --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fountain_v11; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class FountainView extends RSSurfaceView { + + public FountainView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private FountainRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new FountainRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + int act = ev.getActionMasked(); + if (act == ev.ACTION_UP) { + mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0)); + return false; + } else if (act == MotionEvent.ACTION_POINTER_UP) { + // only one pointer going up, we can get the index like this + int pointerIndex = ev.getActionIndex(); + int pointerId = ev.getPointerId(pointerIndex); + mRender.newTouchPosition(0, 0, 0, pointerId); + } + int count = ev.getHistorySize(); + int pcount = ev.getPointerCount(); + + for (int p=0; p < pcount; p++) { + int id = ev.getPointerId(p); + mRender.newTouchPosition(ev.getX(p), + ev.getY(p), + ev.getPressure(p), + id); + + for (int i=0; i < count; i++) { + mRender.newTouchPosition(ev.getHistoricalX(p, i), + ev.getHistoricalY(p, i), + ev.getHistoricalPressure(p, i), + id); + } + } + return true; + } +} + + diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java new file mode 100644 index 0000000..2c07b27 --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.fountain_v11; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class Fountain_v11 extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private FountainView mView; + + // get the current looper (from your Activity UI thread for instance + + + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new FountainView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + Log.e("rs", "onResume"); + + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + Log.e("rs", "onPause"); + + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.pause(); + + + + //Runtime.getRuntime().exit(0); + } + + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} + diff --git a/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs new file mode 100644 index 0000000..3b6c89a --- /dev/null +++ b/tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs @@ -0,0 +1,69 @@ +// Fountain test script +#pragma version(1) + +#pragma rs java_package_name(com.android.fountain_v11) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + +static int newPart = 0; +rs_mesh partMesh; + +typedef struct __attribute__((packed, aligned(4))) Point { + float2 delta; + float2 position; + uchar4 color; +} Point_t; +Point_t *point; + +int root() { + float dt = min(rsGetDt(), 0.1f); + rsgClearColor(0.f, 0.f, 0.f, 1.f); + const float height = rsgGetHeight(); + const int size = rsAllocationGetDimX(rsGetAllocation(point)); + float dy2 = dt * (10.f); + Point_t * p = point; + for (int ct=0; ct < size; ct++) { + p->delta.y += dy2; + p->position += p->delta; + if ((p->position.y > height) && (p->delta.y > 0)) { + p->delta.y *= -0.3f; + } + p++; + } + + rsgDrawMesh(partMesh); + return 1; +} + +static float4 partColor[10]; +void addParticles(int rate, float x, float y, int index, bool newColor) +{ + if (newColor) { + partColor[index].x = rsRand(0.5f, 1.0f); + partColor[index].y = rsRand(1.0f); + partColor[index].z = rsRand(1.0f); + } + float rMax = ((float)rate) * 0.02f; + int size = rsAllocationGetDimX(rsGetAllocation(point)); + uchar4 c = rsPackColorTo8888(partColor[index]); + + Point_t * np = &point[newPart]; + float2 p = {x, y}; + while (rate--) { + float angle = rsRand(3.14f * 2.f); + float len = rsRand(rMax); + np->delta.x = len * sin(angle); + np->delta.y = len * cos(angle); + np->position = p; + np->color = c; + newPart++; + np++; + if (newPart >= size) { + newPart = 0; + np = &point[newPart]; + } + } +} + diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index 3615f60..7368260 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -283,6 +283,9 @@ public class ImageProcessingActivity extends Activity mRadius = MAX_RADIUS; mScript.set_radius(mRadius); + mScript.invoke_filter(); + mRS.finish(); + long t = java.lang.System.currentTimeMillis(); mScript.invoke_filter(); diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs index 86479d5..ee83496 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs @@ -1,4 +1,5 @@ #pragma version(1) +#pragma rs_fp_relaxed #include "ip.rsh" diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs index 8b07bc2..a6da192 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs @@ -1,4 +1,5 @@ #pragma version(1) +#pragma rs_fp_relaxed #include "ip.rsh" diff --git a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs index 8cec409..de2a0a7 100644 --- a/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs +++ b/tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs @@ -48,6 +48,14 @@ static float gZoom; static float gLastX; static float gLastY; +static float3 toFloat3(float x, float y, float z) { + float3 f; + f.x = x; + f.y = y; + f.z = z; + return f; +} + void onActionDown(float x, float y) { gLastX = x; gLastY = y; @@ -104,8 +112,8 @@ void updateMeshInfo() { rsgMeshComputeBoundingBox(info->mMesh, &minX, &minY, &minZ, &maxX, &maxY, &maxZ); - info->bBoxMin = (minX, minY, minZ); - info->bBoxMax = (maxX, maxY, maxZ); + info->bBoxMin = toFloat3(minX, minY, minZ); + info->bBoxMax = toFloat3(maxX, maxY, maxZ); gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; } gLookAt = gLookAt / (float)size; diff --git a/tests/RenderScriptTests/PerfTest/res/menu/loader_menu.xml b/tests/RenderScriptTests/PerfTest/res/menu/loader_menu.xml index 8234677..59a251d 100644 --- a/tests/RenderScriptTests/PerfTest/res/menu/loader_menu.xml +++ b/tests/RenderScriptTests/PerfTest/res/menu/loader_menu.xml @@ -18,8 +18,11 @@ --> <menu xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:id="@+id/benchmark_mode" - android:title="@string/benchmark_mode" /> + <item android:id="@+id/benchmark_all" + android:title="@string/benchmark_all" /> + <item android:id="@+id/benchmark_one" + android:title="@string/benchmark_one" /> <item android:id="@+id/debug_mode" android:title="@string/debug_mode" /> </menu> + diff --git a/tests/RenderScriptTests/PerfTest/res/raw/singletexf.glsl b/tests/RenderScriptTests/PerfTest/res/raw/singletexf.glsl new file mode 100644 index 0000000..83dfc7f --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/raw/singletexf.glsl @@ -0,0 +1,8 @@ +varying vec2 varTex0; + +void main() { + lowp vec3 col0 = texture2D(UNI_Tex0, varTex0).rgb; + gl_FragColor.xyz = col0; + gl_FragColor.w = 0.5; +} + diff --git a/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl b/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl new file mode 100644 index 0000000..656961c --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl @@ -0,0 +1,8 @@ +varying vec2 varTex0; + +void main() { + lowp vec3 col0 = texture2D(UNI_Tex0, varTex0).rgb; + gl_FragColor.xyz = col0 * UNI_modulate.rgb; + gl_FragColor.w = UNI_modulate.a; +} + diff --git a/tests/RenderScriptTests/PerfTest/res/values/strings.xml b/tests/RenderScriptTests/PerfTest/res/values/strings.xml index 627ac21..ce9819e 100644 --- a/tests/RenderScriptTests/PerfTest/res/values/strings.xml +++ b/tests/RenderScriptTests/PerfTest/res/values/strings.xml @@ -19,6 +19,8 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <skip /> - <string name="benchmark_mode">Benchmark Mode</string> + <string name="benchmark_all">Benchmark All</string> + <string name="benchmark_one">Benchmark One</string> <string name="debug_mode">Debug Mode</string> </resources> + diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java new file mode 100644 index 0000000..41f664a --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; + +import android.os.Environment; +import android.content.res.Resources; +import android.renderscript.*; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + + +import android.util.Log; + + +public class FillTest implements RsBenchBaseTest{ + + private static final String TAG = "FillTest"; + private RenderScriptGL mRS; + private Resources mRes; + + // Custom shaders + private ProgramFragment mProgFragmentMultitex; + private ProgramFragment mProgFragmentSingletex; + private ProgramFragment mProgFragmentSingletexModulate; + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + int mBenchmarkDimX; + int mBenchmarkDimY; + + private ScriptC_fill_test mFillScript; + ScriptField_TestScripts_s.Item[] mTests; + ScriptField_FillTestFragData_s mFragData; + + private final String[] mNames = { + "Fill screen 10x singletexture", + "Fill screen 10x 3tex multitexture", + "Fill screen 10x blended singletexture", + "Fill screen 10x blended 3tex multitexture", + "Fill screen 3x modulate blended singletexture", + "Fill screen 1x modulate blended singletexture", + }; + + public FillTest() { + mOptionsARGB.inScaled = false; + mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; + mBenchmarkDimX = 1280; + mBenchmarkDimY = 720; + } + + void addTest(int index, int testId, int blend, int quadCount) { + mTests[index] = new ScriptField_TestScripts_s.Item(); + mTests[index].testScript = mFillScript; + mTests[index].testName = Allocation.createFromString(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + + ScriptField_FillTestData_s.Item dataItem = new ScriptField_FillTestData_s.Item(); + dataItem.testId = testId; + dataItem.blend = blend; + dataItem.quadCount = quadCount; + ScriptField_FillTestData_s testData = new ScriptField_FillTestData_s(mRS, 1); + testData.set(dataItem, 0, true); + mTests[index].testData = testData.getAllocation(); + } + + public boolean init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initCustomShaders(); + initFillScript(); + mTests = new ScriptField_TestScripts_s.Item[mNames.length]; + + int index = 0; + + addTest(index++, 1 /*testId*/, 0 /*blend*/, 10 /*quadCount*/); + addTest(index++, 0 /*testId*/, 0 /*blend*/, 10 /*quadCount*/); + addTest(index++, 1 /*testId*/, 1 /*blend*/, 10 /*quadCount*/); + addTest(index++, 0 /*testId*/, 1 /*blend*/, 10 /*quadCount*/); + addTest(index++, 2 /*testId*/, 1 /*blend*/, 3 /*quadCount*/); + addTest(index++, 2 /*testId*/, 1 /*blend*/, 1 /*quadCount*/); + + return true; + } + + public ScriptField_TestScripts_s.Item[] getTests() { + return mTests; + } + + public String[] getTestNames() { + return mNames; + } + + private void initCustomShaders() { + ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS); + pfbCustom.setShader(mRes, R.raw.multitexf); + for (int texCount = 0; texCount < 3; texCount ++) { + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + } + mProgFragmentMultitex = pfbCustom.create(); + + pfbCustom = new ProgramFragment.Builder(mRS); + pfbCustom.setShader(mRes, R.raw.singletexf); + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + mProgFragmentSingletex = pfbCustom.create(); + + pfbCustom = new ProgramFragment.Builder(mRS); + pfbCustom.setShader(mRes, R.raw.singletexfm); + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + mFragData = new ScriptField_FillTestFragData_s(mRS, 1); + pfbCustom.addConstant(mFragData.getType()); + mProgFragmentSingletexModulate = pfbCustom.create(); + mProgFragmentSingletexModulate.bindConstants(mFragData.getAllocation(), 0); + } + + private Allocation loadTextureARGB(int id) { + Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); + return Allocation.createFromBitmap(mRS, b, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + private Allocation loadTextureRGB(int id) { + return Allocation.createFromBitmapResource(mRS, mRes, id, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + void initFillScript() { + mFillScript = new ScriptC_fill_test(mRS, mRes, R.raw.fill_test); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertexFixedFunction progVertex = pvb.create(); + ProgramVertexFixedFunction.Constants PVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)progVertex).bindConstants(PVA); + Matrix4f proj = new Matrix4f(); + proj.loadOrthoWindow(mBenchmarkDimX, mBenchmarkDimY); + PVA.setProjection(proj); + mFillScript.set_gProgVertex(progVertex); + + mFillScript.set_gProgFragmentTexture(mProgFragmentSingletex); + mFillScript.set_gProgFragmentTextureModulate(mProgFragmentSingletexModulate); + mFillScript.set_gProgFragmentMultitex(mProgFragmentMultitex); + mFillScript.set_gProgStoreBlendNone(ProgramStore.BLEND_NONE_DEPTH_NONE(mRS)); + mFillScript.set_gProgStoreBlendAlpha(ProgramStore.BLEND_ALPHA_DEPTH_NONE(mRS)); + + mFillScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); + mFillScript.set_gLinearWrap(Sampler.WRAP_LINEAR(mRS)); + mFillScript.set_gTexTorus(loadTextureRGB(R.drawable.torusmap)); + mFillScript.set_gTexOpaque(loadTextureRGB(R.drawable.data)); + mFillScript.set_gTexTransparent(loadTextureARGB(R.drawable.leaf)); + mFillScript.set_gTexChecker(loadTextureRGB(R.drawable.checker)); + + mFillScript.bind_gFragData(mFragData); + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java new file mode 100644 index 0000000..cdb4435 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; + +import android.os.Environment; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.renderscript.*; +import android.renderscript.Element.DataKind; +import android.renderscript.Element.DataType; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Program.TextureType; +import android.renderscript.RenderScript.RSMessageHandler; +import android.renderscript.Mesh.Primitive; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramVertexFixedFunction; + +import android.util.Log; + + +public class MeshTest implements RsBenchBaseTest{ + + private static final String TAG = "MeshTest"; + private RenderScriptGL mRS; + private Resources mRes; + + int mBenchmarkDimX; + int mBenchmarkDimY; + + private Mesh m10by10Mesh; + private Mesh m100by100Mesh; + private Mesh mWbyHMesh; + + private ScriptC_mesh_test mGeoScript; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + ScriptField_TestScripts_s.Item[] mTests; + + private final String[] mNames = { + "Full screen mesh 10 by 10", + "Full screen mesh 100 by 100", + "Full screen mesh W / 4 by H / 4" + }; + + public MeshTest() { + mBenchmarkDimX = 1280; + mBenchmarkDimY = 720; + } + + void addTest(int index, int meshNum) { + mTests[index] = new ScriptField_TestScripts_s.Item(); + mTests[index].testScript = mGeoScript; + mTests[index].testName = Allocation.createFromString(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + + ScriptField_MeshTestData_s.Item dataItem = new ScriptField_MeshTestData_s.Item(); + dataItem.meshNum = meshNum; + ScriptField_MeshTestData_s testData = new ScriptField_MeshTestData_s(mRS, 1); + testData.set(dataItem, 0, true); + mTests[index].testData = testData.getAllocation(); + } + + public boolean init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initGeoScript(); + mTests = new ScriptField_TestScripts_s.Item[mNames.length]; + + int index = 0; + addTest(index++, 0 /*meshNum*/); + addTest(index++, 1 /*meshNum*/); + addTest(index++, 2 /*meshNum*/); + + return true; + } + + public ScriptField_TestScripts_s.Item[] getTests() { + return mTests; + } + + public String[] getTestNames() { + return mNames; + } + + private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) { + + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, + 2, Mesh.TriangleMeshBuilder.TEXTURE_0); + + for (int y = 0; y <= hResolution; y++) { + final float normalizedY = (float)y / hResolution; + final float yOffset = (normalizedY - 0.5f) * height; + for (int x = 0; x <= wResolution; x++) { + float normalizedX = (float)x / wResolution; + float xOffset = (normalizedX - 0.5f) * width; + tmb.setTexture((float)x % 2, (float)y % 2); + tmb.addVertex(xOffset, yOffset); + } + } + + for (int y = 0; y < hResolution; y++) { + final int curY = y * (wResolution + 1); + final int belowY = (y + 1) * (wResolution + 1); + for (int x = 0; x < wResolution; x++) { + int curV = curY + x; + int belowV = belowY + x; + tmb.addTriangle(curV, belowV, curV + 1); + tmb.addTriangle(belowV, belowV + 1, curV + 1); + } + } + + return tmb.create(true); + } + + private Allocation loadTextureRGB(int id) { + return Allocation.createFromBitmapResource(mRS, mRes, id, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + void initGeoScript() { + mGeoScript = new ScriptC_mesh_test(mRS, mRes, R.raw.mesh_test); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertexFixedFunction progVertex = pvb.create(); + ProgramVertexFixedFunction.Constants PVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)progVertex).bindConstants(PVA); + Matrix4f proj = new Matrix4f(); + proj.loadOrthoWindow(mBenchmarkDimX, mBenchmarkDimY); + PVA.setProjection(proj); + + mGeoScript.set_gProgVertex(progVertex); + ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS); + texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + mGeoScript.set_gProgFragmentTexture(texBuilder.create()); + mGeoScript.set_gProgStoreBlendNone(ProgramStore.BLEND_NONE_DEPTH_NONE(mRS)); + + mGeoScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); + mGeoScript.set_gTexOpaque(loadTextureRGB(R.drawable.data)); + + m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10); + m100by100Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 100, 100); + mWbyHMesh= getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, mBenchmarkDimX/4, mBenchmarkDimY/4); + + mGeoScript.set_g10by10Mesh(m10by10Mesh); + mGeoScript.set_g100by100Mesh(m100by100Mesh); + mGeoScript.set_gWbyHMesh(mWbyHMesh); + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java index b336a4d..0dceafe 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java @@ -93,22 +93,41 @@ public class RsBench extends Activity { public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection switch (item.getItemId()) { - case R.id.benchmark_mode: - mView.setBenchmarkMode(); + case R.id.benchmark_all: + mView.setBenchmarkMode(-1); + mView.suspendRendering(false); return true; - case R.id.debug_mode: + case R.id.benchmark_one: + mView.suspendRendering(true); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a Test"); builder.setItems(mView.getTestNames(), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), + "Starting to benchmark: " + mView.getTestNames()[item], + Toast.LENGTH_SHORT).show(); + mView.setBenchmarkMode(item); + mView.suspendRendering(false); + } + }); + builder.show(); + return true; + case R.id.debug_mode: + mView.suspendRendering(true); + AlertDialog.Builder debugBuilder = new AlertDialog.Builder(this); + debugBuilder.setTitle("Pick a Test"); + debugBuilder.setItems(mView.getTestNames(), + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int item) { + Toast.makeText(getApplicationContext(), "Switching to: " + mView.getTestNames()[item], Toast.LENGTH_SHORT).show(); mView.setDebugMode(item); + mView.suspendRendering(false); } }); - builder.show(); + debugBuilder.show(); return true; default: return super.onOptionsItemSelected(item); diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchBaseTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchBaseTest.java new file mode 100644 index 0000000..a9e1777 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchBaseTest.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; +import android.renderscript.*; +import android.content.res.Resources; + +interface RsBenchBaseTest { + boolean init(RenderScriptGL rs, Resources res); + + ScriptField_TestScripts_s.Item[] getTests(); + String[] getTestNames(); +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java index c375be5..4ac7dd5 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2010-2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,16 +26,11 @@ import java.io.OutputStream; import android.os.Environment; import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.renderscript.*; import android.renderscript.Element.DataKind; import android.renderscript.Element.DataType; import android.renderscript.Allocation.MipmapControl; import android.renderscript.Program.TextureType; -import android.renderscript.ProgramStore.DepthFunc; -import android.renderscript.ProgramStore.BlendSrcFunc; -import android.renderscript.ProgramStore.BlendDstFunc; import android.renderscript.RenderScript.RSMessageHandler; import android.renderscript.Sampler.Value; import android.renderscript.Mesh.Primitive; @@ -48,10 +43,6 @@ import android.util.Log; public class RsBenchRS { private static final String TAG = "RsBenchRS"; - private static final String SAMPLE_TEXT = "Bench Test"; - private static final String LIST_TEXT = - "This is a sample list of text to show in the list view"; - private static int PARTICLES_COUNT = 12000; int mWidth; int mHeight; int mLoops; @@ -68,10 +59,7 @@ public class RsBenchRS { mRes = res; mWidth = width; mHeight = height; - mOptionsARGB.inScaled = false; - mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; mMode = 0; - mMaxModes = 0; mLoops = loops; mCurrentLoop = 0; mBenchmarkDimX = 1280; @@ -84,10 +72,8 @@ public class RsBenchRS { private Resources mRes; private RenderScriptGL mRS; - private ProgramStore mProgStoreBlendNoneDepth; private ProgramStore mProgStoreBlendNone; private ProgramStore mProgStoreBlendAlpha; - private ProgramStore mProgStoreBlendAdd; private ProgramFragment mProgFragmentTexture; private ProgramFragment mProgFragmentColor; @@ -96,58 +82,69 @@ public class RsBenchRS { private ProgramVertexFixedFunction.Constants mPVA; private ProgramVertexFixedFunction.Constants mPvProjectionAlloc; - // Custom shaders - private ProgramVertex mProgVertexCustom; - private ProgramFragment mProgFragmentCustom; - private ProgramFragment mProgFragmentMultitex; - private ProgramVertex mProgVertexPixelLight; - private ProgramVertex mProgVertexPixelLightMove; - private ProgramFragment mProgFragmentPixelLight; - private ScriptField_VertexShaderConstants_s mVSConst; - private ScriptField_FragentShaderConstants_s mFSConst; - private ScriptField_VertexShaderConstants3_s mVSConstPixel; - private ScriptField_FragentShaderConstants3_s mFSConstPixel; - - - private Allocation mTexTorus; - private Allocation mTexOpaque; - private Allocation mTexTransparent; - private Allocation mTexChecker; - private Allocation mTexGlobe; - - private Mesh m10by10Mesh; - private Mesh m100by100Mesh; - private Mesh mWbyHMesh; - private Mesh mTorus; - private Mesh mSingleMesh; - private Mesh mParticlesMesh; - - Font mFontSans; - Font mFontSerif; - private Allocation mTextAlloc; - - private ScriptField_ListAllocs_s mTextureAllocs; - private ScriptField_ListAllocs_s mSampleTextAllocs; - private ScriptField_ListAllocs_s mSampleListViewAllocs; - private ScriptField_VpConsts mPvStarAlloc; - - private ScriptC_rsbench mScript; - private ScriptC_text_test mTextScript; - private ScriptC_torus_test mTorusScript; - private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + ScriptField_TestScripts_s.Item[] mIndividualTests; int mMode; - int mMaxModes; String[] mTestNames; float[] mLocalTestResults; - public void onActionDown(int x, int y) { - mMode ++; - mMode = mMode % mMaxModes; - mScript.set_gDisplayMode(mMode); + static Allocation createZeroTerminatedAlloc(RenderScript rs, + String str, + int usage) { + byte[] allocArray = null; + try { + allocArray = str.getBytes("UTF-8"); + byte[] allocArrayZero = new byte[allocArray.length + 1]; + System.arraycopy(allocArray, 0, allocArrayZero, 0, allocArray.length); + allocArrayZero[allocArrayZero.length - 1] = '\0'; + Allocation alloc = Allocation.createSized(rs, Element.U8(rs), + allocArrayZero.length, usage); + alloc.copyFrom(allocArrayZero); + return alloc; + } + catch (Exception e) { + throw new RSRuntimeException("Could not convert string to utf-8."); + } + + } + + void appendTests(RsBenchBaseTest testSet) { + ScriptField_TestScripts_s.Item[] newTests = testSet.getTests(); + if (mIndividualTests != null) { + ScriptField_TestScripts_s.Item[] combined; + combined = new ScriptField_TestScripts_s.Item[newTests.length + mIndividualTests.length]; + System.arraycopy(mIndividualTests, 0, combined, 0, mIndividualTests.length); + System.arraycopy(newTests, 0, combined, mIndividualTests.length, newTests.length); + mIndividualTests = combined; + } else { + mIndividualTests = newTests; + } + + String[] newNames = testSet.getTestNames(); + if (mTestNames != null) { + String[] combinedNames; + combinedNames = new String[newNames.length + mTestNames.length]; + System.arraycopy(mTestNames, 0, combinedNames, 0, mTestNames.length); + System.arraycopy(newNames, 0, combinedNames, mTestNames.length, newNames.length); + mTestNames = combinedNames; + } else { + mTestNames = newNames; + } + } + + void createTestAllocation() { + int numTests = mIndividualTests.length; + mLocalTestResults = new float[numTests]; + ScriptField_TestScripts_s allTests; + allTests = new ScriptField_TestScripts_s(mRS, numTests); + for (int i = 0; i < numTests; i ++) { + allTests.set(mIndividualTests[i], i, false); + } + allTests.copyAll(); + mScript.bind_gTestScripts(allTests); } private void saveTestResults() { @@ -225,98 +222,6 @@ public class RsBenchRS { } } - ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) { - ProgramStore.Builder builder = new ProgramStore.Builder(rs); - builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); - builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE); - builder.setDitherEnabled(false); - builder.setDepthMaskEnabled(false); - return builder.create(); - } - - private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) { - - Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, - 2, Mesh.TriangleMeshBuilder.TEXTURE_0); - - for (int y = 0; y <= hResolution; y++) { - final float normalizedY = (float)y / hResolution; - final float yOffset = (normalizedY - 0.5f) * height; - for (int x = 0; x <= wResolution; x++) { - float normalizedX = (float)x / wResolution; - float xOffset = (normalizedX - 0.5f) * width; - tmb.setTexture((float)x % 2, (float)y % 2); - tmb.addVertex(xOffset, yOffset); - } - } - - for (int y = 0; y < hResolution; y++) { - final int curY = y * (wResolution + 1); - final int belowY = (y + 1) * (wResolution + 1); - for (int x = 0; x < wResolution; x++) { - int curV = curY + x; - int belowV = belowY + x; - tmb.addTriangle(curV, belowV, curV + 1); - tmb.addTriangle(belowV, belowV + 1, curV + 1); - } - } - - return tmb.create(true); - } - - /** - * Create a mesh with a single quad for the given width and height. - */ - private Mesh getSingleMesh(float width, float height) { - Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, - 2, Mesh.TriangleMeshBuilder.TEXTURE_0); - float xOffset = width/2; - float yOffset = height/2; - tmb.setTexture(0, 0); - tmb.addVertex(-1.0f * xOffset, -1.0f * yOffset); - tmb.setTexture(1, 0); - tmb.addVertex(xOffset, -1.0f * yOffset); - tmb.setTexture(1, 1); - tmb.addVertex(xOffset, yOffset); - tmb.setTexture(0, 1); - tmb.addVertex(-1.0f * xOffset, yOffset); - tmb.addTriangle(0, 3, 1); - tmb.addTriangle(1, 3, 2); - return tmb.create(true); - } - - private void initProgramStore() { - // Use stock the stock program store object - mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS); - mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS); - - // Create a custom program store - ProgramStore.Builder builder = new ProgramStore.Builder(mRS); - builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); - builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, - ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); - builder.setDitherEnabled(false); - builder.setDepthMaskEnabled(false); - mProgStoreBlendAlpha = builder.create(); - - mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS); - - mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth); - - mScript.set_gProgStoreBlendNone(mProgStoreBlendNone); - mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha); - mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd); - - // For GALAXY - builder = new ProgramStore.Builder(mRS); - builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); - mRS.bindProgramStore(builder.create()); - - builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); - mScript.set_gPSLights(builder.create()); - - } - private void initProgramFragment() { ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS); @@ -329,64 +234,9 @@ public class RsBenchRS { colBuilder.setVaryingColor(false); mProgFragmentColor = colBuilder.create(); - mScript.set_gProgFragmentColor(mProgFragmentColor); - mScript.set_gProgFragmentTexture(mProgFragmentTexture); - - - - // For Galaxy live wallpaper drawing - ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); - builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, - ProgramFragmentFixedFunction.Builder.Format.RGB, 0); - ProgramFragment pfb = builder.create(); - pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0); - mScript.set_gPFBackground(pfb); - - builder = new ProgramFragmentFixedFunction.Builder(mRS); - builder.setPointSpriteTexCoordinateReplacement(true); - builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, - ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); - builder.setVaryingColor(true); - ProgramFragment pfs = builder.create(); - pfs.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); - mScript.set_gPFStars(pfs); - } - private Matrix4f getProjectionNormalized(int w, int h) { - // range -1,1 in the narrow axis at z = 0. - Matrix4f m1 = new Matrix4f(); - Matrix4f m2 = new Matrix4f(); - - if(w > h) { - float aspect = ((float)w) / h; - m1.loadFrustum(-aspect,aspect, -1,1, 1,100); - } else { - float aspect = ((float)h) / w; - m1.loadFrustum(-1,1, -aspect,aspect, 1,100); - } - - m2.loadRotate(180, 0, 1, 0); - m1.loadMultiply(m1, m2); - - m2.loadScale(-2, 2, 1); - m1.loadMultiply(m1, m2); - - m2.loadTranslate(0, 0, 2); - m1.loadMultiply(m1, m2); - return m1; - } - - private void updateProjectionMatrices() { - Matrix4f projNorm = getProjectionNormalized(mBenchmarkDimX, mBenchmarkDimY); - ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); - i.Proj = projNorm; - i.MVP = projNorm; - mPvStarAlloc.set(i, 0, true); - mPvProjectionAlloc.setProjection(projNorm); - } - private void initProgramVertex() { ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); mProgVertex = pvb.create(); @@ -398,201 +248,6 @@ public class RsBenchRS { mPVA.setProjection(proj); mScript.set_gProgVertex(mProgVertex); - - - // For galaxy live wallpaper - mPvStarAlloc = new ScriptField_VpConsts(mRS, 1); - mScript.bind_vpConstants(mPvStarAlloc); - mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS); - updateProjectionMatrices(); - - pvb = new ProgramVertexFixedFunction.Builder(mRS); - ProgramVertex pvbp = pvb.create(); - ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc); - mScript.set_gPVBkProj(pvbp); - - ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); - String t = "varying vec4 varColor;\n" + - "varying vec2 varTex0;\n" + - "void main() {\n" + - " float dist = ATTRIB_position.y;\n" + - " float angle = ATTRIB_position.x;\n" + - " float x = dist * sin(angle);\n" + - " float y = dist * cos(angle) * 0.892;\n" + - " float p = dist * 5.5;\n" + - " float s = cos(p);\n" + - " float t = sin(p);\n" + - " vec4 pos;\n" + - " pos.x = t * x + s * y;\n" + - " pos.y = s * x - t * y;\n" + - " pos.z = ATTRIB_position.z;\n" + - " pos.w = 1.0;\n" + - " gl_Position = UNI_MVP * pos;\n" + - " gl_PointSize = ATTRIB_color.a * 10.0;\n" + - " varColor.rgb = ATTRIB_color.rgb;\n" + - " varColor.a = 1.0;\n" + - "}\n"; - sb.setShader(t); - sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement()); - sb.addConstant(mPvStarAlloc.getType()); - ProgramVertex pvs = sb.create(); - pvs.bindConstants(mPvStarAlloc.getAllocation(), 0); - mScript.set_gPVStars(pvs); - } - - private void initCustomShaders() { - mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1); - mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1); - - - mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1); - mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1); - - - // Initialize the shader builder - ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS); - // Specify the resource that contains the shader string - pvbCustom.setShader(mRes, R.raw.shaderv); - // Use a script field to specify the input layout - pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); - // Define the constant input layout - pvbCustom.addConstant(mVSConst.getAllocation().getType()); - mProgVertexCustom = pvbCustom.create(); - // Bind the source of constant data - mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0); - - ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS); - // Specify the resource that contains the shader string - pfbCustom.setShader(mRes, R.raw.shaderf); - // Tell the builder how many textures we have - pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); - // Define the constant input layout - pfbCustom.addConstant(mFSConst.getAllocation().getType()); - mProgFragmentCustom = pfbCustom.create(); - // Bind the source of constant data - mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0); - - pvbCustom = new ProgramVertex.Builder(mRS); - pvbCustom.setShader(mRes, R.raw.shader2v); - pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); - pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); - mProgVertexPixelLight = pvbCustom.create(); - mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0); - - pvbCustom = new ProgramVertex.Builder(mRS); - pvbCustom.setShader(mRes, R.raw.shader2movev); - pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); - pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); - mProgVertexPixelLightMove = pvbCustom.create(); - mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0); - - pfbCustom = new ProgramFragment.Builder(mRS); - pfbCustom.setShader(mRes, R.raw.shader2f); - pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); - pfbCustom.addConstant(mFSConstPixel.getAllocation().getType()); - mProgFragmentPixelLight = pfbCustom.create(); - mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0); - - pfbCustom = new ProgramFragment.Builder(mRS); - pfbCustom.setShader(mRes, R.raw.multitexf); - for (int texCount = 0; texCount < 3; texCount ++) { - pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); - } - mProgFragmentMultitex = pfbCustom.create(); - - - mScript.set_gProgFragmentMultitex(mProgFragmentMultitex); - } - - private Allocation loadTextureRGB(int id) { - return Allocation.createFromBitmapResource(mRS, mRes, id, - Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, - Allocation.USAGE_GRAPHICS_TEXTURE); - } - - private Allocation loadTextureARGB(int id) { - Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); - return Allocation.createFromBitmap(mRS, b, - Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, - Allocation.USAGE_GRAPHICS_TEXTURE); - } - - private void loadImages() { - mTexTorus = loadTextureRGB(R.drawable.torusmap); - mTexOpaque = loadTextureRGB(R.drawable.data); - mTexTransparent = loadTextureARGB(R.drawable.leaf); - mTexChecker = loadTextureRGB(R.drawable.checker); - mTexGlobe = loadTextureRGB(R.drawable.globe); - - mScript.set_gTexTorus(mTexTorus); - mScript.set_gTexOpaque(mTexOpaque); - mScript.set_gTexTransparent(mTexTransparent); - mScript.set_gTexChecker(mTexChecker); - mScript.set_gTexGlobe(mTexGlobe); - - // For Galaxy live wallpaper - mScript.set_gTSpace(loadTextureRGB(R.drawable.space)); - mScript.set_gTLight1(loadTextureRGB(R.drawable.light1)); - mScript.set_gTFlares(loadTextureARGB(R.drawable.flares)); - } - - private void initFonts() { - // Sans font by family name - mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8); - mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8); - // Create fonts by family and style - - mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT); - - mScript.set_gFontSans(mFontSans); - mScript.set_gFontSerif(mFontSerif); - } - - private void createParticlesMesh() { - ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT); - - final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); - meshBuilder.addVertexAllocation(p.getAllocation()); - final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex(); - meshBuilder.addIndexSetType(Primitive.POINT); - mParticlesMesh = meshBuilder.create(); - - mScript.set_gParticlesMesh(mParticlesMesh); - mScript.bind_Particles(p); - } - - private void initMesh() { - m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10); - mScript.set_g10by10Mesh(m10by10Mesh); - m100by100Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 100, 100); - mScript.set_g100by100Mesh(m100by100Mesh); - mWbyHMesh= getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, mBenchmarkDimX/4, mBenchmarkDimY/4); - mScript.set_gWbyHMesh(mWbyHMesh); - mSingleMesh = getSingleMesh(1, 1); // a unit size mesh - mScript.set_gSingleMesh(mSingleMesh); - - FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus); - FileA3D.IndexEntry entry = model.getIndexEntry(0); - if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) { - Log.e("rs", "could not load model"); - } else { - mTorus = (Mesh)entry.getObject(); - } - - createParticlesMesh(); - } - - private void initSamplers() { - mScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); - mScript.set_gLinearWrap(Sampler.WRAP_LINEAR(mRS)); - mScript.set_gMipLinearWrap(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS)); - mScript.set_gNearestClamp(Sampler.CLAMP_NEAREST(mRS)); - } - - private void initProgramRaster() { - mScript.set_gCullBack(ProgramRaster.CULL_BACK(mRS)); - mScript.set_gCullFront(ProgramRaster.CULL_FRONT(mRS)); - mScript.set_gCullNone(ProgramRaster.CULL_NONE(mRS)); } private int strlen(byte[] array) { @@ -603,78 +258,30 @@ public class RsBenchRS { return count; } - private void prepareTestData() { - mTestNames = new String[mMaxModes]; - mLocalTestResults = new float[mMaxModes]; - int scratchSize = 1024; - Allocation scratch = Allocation.createSized(mRS, Element.U8(mRS), scratchSize); - byte[] tmp = new byte[scratchSize]; - mScript.bind_gStringBuffer(scratch); - for (int i = 0; i < mMaxModes; i ++) { - mScript.invoke_getTestName(i); - scratch.copyTo(tmp); - int len = strlen(tmp); - mTestNames[i] = new String(tmp, 0, len); - } - } - public void setDebugMode(int num) { mScript.invoke_setDebugMode(num); } - public void setBenchmarkMode() { - mScript.invoke_setBenchmarkMode(); + public void setBenchmarkMode(int benchNum) { + mScript.invoke_setBenchmarkMode(benchNum); } - void initTextScript() { - mTextScript = new ScriptC_text_test(mRS, mRes, R.raw.text_test); - mTextScript.set_gFontSans(mFontSans); - mTextScript.set_gFontSerif(mFontSerif); - } - - void initTorusScript() { - mTorusScript = new ScriptC_torus_test(mRS, mRes, R.raw.torus_test); - mTorusScript.set_gCullFront(ProgramRaster.CULL_FRONT(mRS)); - mTorusScript.set_gCullBack(ProgramRaster.CULL_BACK(mRS)); - mTorusScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); - mTorusScript.set_gTorusMesh(mTorus); - mTorusScript.set_gTexTorus(mTexTorus); - mTorusScript.set_gProgVertexCustom(mProgVertexCustom); - mTorusScript.set_gProgFragmentCustom(mProgFragmentCustom); - mTorusScript.set_gProgVertexPixelLight(mProgVertexPixelLight); - mTorusScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove); - mTorusScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight); - mTorusScript.bind_gVSConstPixel(mVSConstPixel); - mTorusScript.bind_gFSConstPixel(mFSConstPixel); - mTorusScript.bind_gVSConstants(mVSConst); - mTorusScript.bind_gFSConstants(mFSConst); - mTorusScript.set_gProgVertex(mProgVertex); - mTorusScript.set_gProgFragmentTexture(mProgFragmentTexture); - mTorusScript.set_gProgFragmentColor(mProgFragmentColor); - mTorusScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth); + public void pause(boolean pause) { + mScript.set_gPauseRendering(pause); } private void initRS() { mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench); - + mRS.bindRootScript(mScript); mRS.setMessageHandler(mRsMessage); - mMaxModes = mScript.get_gMaxModes(); mScript.set_gMaxLoops(mLoops); - prepareTestData(); - - initSamplers(); - initMesh(); initProgramVertex(); - initProgramStore(); initProgramFragment(); - initFonts(); - loadImages(); - initProgramRaster(); - initCustomShaders(); + mScript.set_gFontSerif(Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8)); Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS)); b.setX(mBenchmarkDimX).setY(mBenchmarkDimY); @@ -692,41 +299,30 @@ public class RsBenchRS { b.create(), Allocation.USAGE_GRAPHICS_RENDER_TARGET); mScript.set_gRenderBufferDepth(offscreen); + mScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); - mTextureAllocs = new ScriptField_ListAllocs_s(mRS, 100); - for (int i = 0; i < 100; i++) { - ScriptField_ListAllocs_s.Item texElem = new ScriptField_ListAllocs_s.Item(); - texElem.item = loadTextureRGB(R.drawable.globe); - mTextureAllocs.set(texElem, i, false); + RsBenchBaseTest test = new TextTest(); + if (test.init(mRS, mRes)) { + appendTests(test); } - mTextureAllocs.copyAll(); - mScript.bind_gTexList100(mTextureAllocs); - - mSampleTextAllocs = new ScriptField_ListAllocs_s(mRS, 100); - for (int i = 0; i < 100; i++) { - ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); - textElem.item = Allocation.createFromString(mRS, SAMPLE_TEXT, Allocation.USAGE_SCRIPT); - mSampleTextAllocs.set(textElem, i, false); + test = new FillTest(); + if (test.init(mRS, mRes)) { + appendTests(test); } - mSampleTextAllocs.copyAll(); - mScript.bind_gSampleTextList100(mSampleTextAllocs); - - mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000); - for (int i = 0; i < 1000; i++) { - ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); - textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT); - mSampleListViewAllocs.set(textElem, i, false); + test = new MeshTest(); + if (test.init(mRS, mRes)) { + appendTests(test); } - mSampleListViewAllocs.copyAll(); - mScript.bind_gListViewText(mSampleListViewAllocs); - - initTextScript(); - initTorusScript(); - - mScript.set_gFontScript(mTextScript); - mScript.set_gTorusScript(mTorusScript); - mScript.set_gDummyAlloc(Allocation.createSized(mRS, Element.I32(mRS), 1)); + test = new TorusTest(); + if (test.init(mRS, mRes)) { + appendTests(test); + } + test = new UiTest(); + if (test.init(mRS, mRes)) { + appendTests(test); + } + createTestAllocation(); - mRS.bindRootScript(mScript); + mScript.set_gLoadComplete(true); } } diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java index 61aa3e1..124071e 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java @@ -71,24 +71,6 @@ public class RsBenchView extends RSSurfaceView { } } - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - return super.onKeyDown(keyCode, event); - } - - - @Override - public boolean onTouchEvent(MotionEvent ev) { - boolean ret = false; - int act = ev.getAction(); - if (act == ev.ACTION_DOWN) { - mRender.onActionDown((int)ev.getX(), (int)ev.getY()); - ret = true; - } - - return ret; - } - /** * Set the total number of loops the benchmark tests will run * before the test results are collected. @@ -106,8 +88,12 @@ public class RsBenchView extends RSSurfaceView { return mRender.testIsFinished(); } - void setBenchmarkMode() { - mRender.setBenchmarkMode(); + void setBenchmarkMode(int benchNum) { + mRender.setBenchmarkMode(benchNum); + } + + void suspendRendering(boolean pause) { + mRender.pause(pause); } void setDebugMode(int num) { diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java new file mode 100644 index 0000000..3ca2792 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; + +import android.os.Environment; +import android.content.res.Resources; +import android.renderscript.*; +import android.util.DisplayMetrics; + +import android.util.Log; + + +public class TextTest implements RsBenchBaseTest{ + + private static final String TAG = "TextTest"; + private RenderScriptGL mRS; + private Resources mRes; + + private ScriptC_text_test mTextScript; + ScriptField_TestScripts_s.Item[] mTests; + + private final String[] mNames = { + "Fill screen with text 1 time", + "Fill screen with text 3 times", + "Fill screen with text 5 times" + }; + + public TextTest() { + } + + void addTest(int index, int fillNum) { + mTests[index] = new ScriptField_TestScripts_s.Item(); + mTests[index].testScript = mTextScript; + mTests[index].testName = Allocation.createFromString(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + + ScriptField_TextTestData_s.Item dataItem = new ScriptField_TextTestData_s.Item(); + dataItem.fillNum = fillNum; + ScriptField_TextTestData_s testData = new ScriptField_TextTestData_s(mRS, 1); + testData.set(dataItem, 0, true); + mTests[index].testData = testData.getAllocation(); + } + + public boolean init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initTextScript(); + mTests = new ScriptField_TestScripts_s.Item[mNames.length]; + + int index = 0; + addTest(index++, 1 /*fillNum*/); + addTest(index++, 3 /*fillNum*/); + addTest(index++, 5 /*fillNum*/); + + return true; + } + + public ScriptField_TestScripts_s.Item[] getTests() { + return mTests; + } + + public String[] getTestNames() { + return mNames; + } + + void initTextScript() { + DisplayMetrics metrics = mRes.getDisplayMetrics(); + + mTextScript = new ScriptC_text_test(mRS, mRes, R.raw.text_test); + mTextScript.set_gFontSans(Font.create(mRS, mRes, "sans-serif", + Font.Style.NORMAL, 8.0f / metrics.density)); + mTextScript.set_gFontSerif(Font.create(mRS, mRes, "serif", + Font.Style.NORMAL, 8.0f / metrics.density)); + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java new file mode 100644 index 0000000..5c9ecd5 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; + +import android.os.Environment; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.renderscript.*; +import android.renderscript.Element.DataKind; +import android.renderscript.Element.DataType; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Program.TextureType; +import android.renderscript.RenderScript.RSMessageHandler; +import android.renderscript.Mesh.Primitive; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramVertexFixedFunction; + +import android.util.Log; + + +public class TorusTest implements RsBenchBaseTest{ + + private static final String TAG = "TorusTest"; + private RenderScriptGL mRS; + private Resources mRes; + + private ProgramStore mProgStoreBlendNoneDepth; + private ProgramStore mProgStoreBlendNone; + private ProgramStore mProgStoreBlendAlpha; + + private ProgramFragment mProgFragmentTexture; + private ProgramFragment mProgFragmentColor; + + private ProgramVertex mProgVertex; + private ProgramVertexFixedFunction.Constants mPVA; + private ProgramVertexFixedFunction.Constants mPvProjectionAlloc; + + // Custom shaders + private ProgramVertex mProgVertexCustom; + private ProgramFragment mProgFragmentCustom; + private ProgramFragment mProgFragmentMultitex; + private ProgramVertex mProgVertexPixelLight; + private ProgramVertex mProgVertexPixelLightMove; + private ProgramFragment mProgFragmentPixelLight; + private ScriptField_VertexShaderConstants_s mVSConst; + private ScriptField_FragentShaderConstants_s mFSConst; + private ScriptField_VertexShaderConstants3_s mVSConstPixel; + private ScriptField_FragentShaderConstants3_s mFSConstPixel; + + private Allocation mTexTorus; + private Mesh mTorus; + + private ScriptC_torus_test mTorusScript; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + ScriptField_TestScripts_s.Item[] mTests; + + private final String[] mNames = { + "Geo test 25.6k flat color", + "Geo test 51.2k flat color", + "Geo test 204.8k small tries flat color", + "Geo test 25.6k single texture", + "Geo test 51.2k single texture", + "Geo test 204.8k small tries single texture", + "Geo test 25.6k geo heavy vertex", + "Geo test 51.2k geo heavy vertex", + "Geo test 204.8k geo raster load heavy vertex", + "Geo test 25.6k heavy fragment", + "Geo test 51.2k heavy fragment", + "Geo test 204.8k small tries heavy fragment", + "Geo test 25.6k heavy fragment heavy vertex", + "Geo test 51.2k heavy fragment heavy vertex", + "Geo test 204.8k small tries heavy fragment heavy vertex" + }; + + public TorusTest() { + } + + void addTest(int index, int testId, int user1, int user2) { + mTests[index] = new ScriptField_TestScripts_s.Item(); + mTests[index].testScript = mTorusScript; + mTests[index].testName = Allocation.createFromString(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + + ScriptField_TorusTestData_s.Item dataItem = new ScriptField_TorusTestData_s.Item(); + dataItem.testId = testId; + dataItem.user1 = user1; + dataItem.user2 = user2; + ScriptField_TorusTestData_s testData = new ScriptField_TorusTestData_s(mRS, 1); + testData.set(dataItem, 0, true); + mTests[index].testData = testData.getAllocation(); + } + + public boolean init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initCustomShaders(); + loadImages(); + initMesh(); + initTorusScript(); + mTests = new ScriptField_TestScripts_s.Item[mNames.length]; + + int index = 0; + addTest(index++, 0, 0 /*useTexture*/, 1 /*numMeshes*/); + addTest(index++, 0, 0 /*useTexture*/, 2 /*numMeshes*/); + addTest(index++, 0, 0 /*useTexture*/, 8 /*numMeshes*/); + addTest(index++, 0, 1 /*useTexture*/, 1 /*numMeshes*/); + addTest(index++, 0, 1 /*useTexture*/, 2 /*numMeshes*/); + addTest(index++, 0, 1 /*useTexture*/, 8 /*numMeshes*/); + + // Secont test + addTest(index++, 1, 1 /*numMeshes*/, 0 /*unused*/); + addTest(index++, 1, 2 /*numMeshes*/, 0 /*unused*/); + addTest(index++, 1, 8 /*numMeshes*/, 0 /*unused*/); + + // Third test + addTest(index++, 2, 1 /*numMeshes*/, 0 /*heavyVertex*/); + addTest(index++, 2, 2 /*numMeshes*/, 0 /*heavyVertex*/); + addTest(index++, 2, 8 /*numMeshes*/, 0 /*heavyVertex*/); + addTest(index++, 2, 1 /*numMeshes*/, 1 /*heavyVertex*/); + addTest(index++, 2, 2 /*numMeshes*/, 1 /*heavyVertex*/); + addTest(index++, 2, 8 /*numMeshes*/, 1 /*heavyVertex*/); + + return true; + } + + public ScriptField_TestScripts_s.Item[] getTests() { + return mTests; + } + + public String[] getTestNames() { + return mNames; + } + + private void initCustomShaders() { + mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1); + mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1); + + mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1); + mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1); + + // Initialize the shader builder + ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS); + // Specify the resource that contains the shader string + pvbCustom.setShader(mRes, R.raw.shaderv); + // Use a script field to specify the input layout + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + // Define the constant input layout + pvbCustom.addConstant(mVSConst.getAllocation().getType()); + mProgVertexCustom = pvbCustom.create(); + // Bind the source of constant data + mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0); + + ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS); + // Specify the resource that contains the shader string + pfbCustom.setShader(mRes, R.raw.shaderf); + // Tell the builder how many textures we have + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + // Define the constant input layout + pfbCustom.addConstant(mFSConst.getAllocation().getType()); + mProgFragmentCustom = pfbCustom.create(); + // Bind the source of constant data + mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0); + + pvbCustom = new ProgramVertex.Builder(mRS); + pvbCustom.setShader(mRes, R.raw.shader2v); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); + mProgVertexPixelLight = pvbCustom.create(); + mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0); + + pvbCustom = new ProgramVertex.Builder(mRS); + pvbCustom.setShader(mRes, R.raw.shader2movev); + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + pvbCustom.addConstant(mVSConstPixel.getAllocation().getType()); + mProgVertexPixelLightMove = pvbCustom.create(); + mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0); + + pfbCustom = new ProgramFragment.Builder(mRS); + pfbCustom.setShader(mRes, R.raw.shader2f); + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + pfbCustom.addConstant(mFSConstPixel.getAllocation().getType()); + mProgFragmentPixelLight = pfbCustom.create(); + mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0); + + pfbCustom = new ProgramFragment.Builder(mRS); + pfbCustom.setShader(mRes, R.raw.multitexf); + for (int texCount = 0; texCount < 3; texCount ++) { + pfbCustom.addTexture(Program.TextureType.TEXTURE_2D); + } + mProgFragmentMultitex = pfbCustom.create(); + + ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS); + colBuilder.setVaryingColor(false); + mProgFragmentColor = colBuilder.create(); + + ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS); + texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + mProgFragmentTexture = texBuilder.create(); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + mProgVertex = pvb.create(); + ProgramVertexFixedFunction.Constants PVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)mProgVertex).bindConstants(PVA); + Matrix4f proj = new Matrix4f(); + proj.loadOrthoWindow(1280, 720); + PVA.setProjection(proj); + } + + private Allocation loadTextureRGB(int id) { + return Allocation.createFromBitmapResource(mRS, mRes, id, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + private void loadImages() { + mTexTorus = loadTextureRGB(R.drawable.torusmap); + } + + private void initMesh() { + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) { + Log.e("rs", "could not load model"); + } else { + mTorus = (Mesh)entry.getObject(); + } + } + + void initTorusScript() { + mTorusScript = new ScriptC_torus_test(mRS, mRes, R.raw.torus_test); + mTorusScript.set_gCullFront(ProgramRaster.CULL_FRONT(mRS)); + mTorusScript.set_gCullBack(ProgramRaster.CULL_BACK(mRS)); + mTorusScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); + mTorusScript.set_gTorusMesh(mTorus); + mTorusScript.set_gTexTorus(mTexTorus); + mTorusScript.set_gProgVertexCustom(mProgVertexCustom); + mTorusScript.set_gProgFragmentCustom(mProgFragmentCustom); + mTorusScript.set_gProgVertexPixelLight(mProgVertexPixelLight); + mTorusScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove); + mTorusScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight); + mTorusScript.bind_gVSConstPixel(mVSConstPixel); + mTorusScript.bind_gFSConstPixel(mFSConstPixel); + mTorusScript.bind_gVSConstants(mVSConst); + mTorusScript.bind_gFSConstants(mFSConst); + mTorusScript.set_gProgVertex(mProgVertex); + mTorusScript.set_gProgFragmentTexture(mProgFragmentTexture); + mTorusScript.set_gProgFragmentColor(mProgFragmentColor); + mTorusScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth); + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java new file mode 100644 index 0000000..c8b58b2 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.perftest; + +import android.os.Environment; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.renderscript.*; +import android.renderscript.Element.DataKind; +import android.renderscript.Element.DataType; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.renderscript.ProgramStore.BlendSrcFunc; +import android.renderscript.ProgramStore.BlendDstFunc; +import android.renderscript.RenderScript.RSMessageHandler; +import android.renderscript.Mesh.Primitive; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramVertexFixedFunction; + +import android.util.Log; + + +public class UiTest implements RsBenchBaseTest{ + + private static final String TAG = "UiTest"; + private static final String SAMPLE_TEXT = "Bench Test"; + private static final String LIST_TEXT = + "This is a sample list of text to show in the list view"; + private static int PARTICLES_COUNT = 12000; + + private RenderScriptGL mRS; + private Resources mRes; + + Font mFontSans; + + private ScriptField_ListAllocs_s mTextureAllocs; + private ScriptField_ListAllocs_s mSampleTextAllocs; + private ScriptField_ListAllocs_s mSampleListViewAllocs; + private ScriptField_VpConsts mPvStarAlloc; + private ProgramVertexFixedFunction.Constants mPvProjectionAlloc; + + private Mesh mSingleMesh; + private Mesh mParticlesMesh; + + private ScriptC_ui_test mUiScript; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + ScriptField_TestScripts_s.Item[] mTests; + + private final String[] mNames = { + "UI test with icon display 10 by 10", + "UI test with icon display 100 by 100", + "UI test with image and text display 3 pages", + "UI test with image and text display 5 pages", + "UI test with list view", + "UI test with live wallpaper" + }; + + public UiTest() { + } + + void addTest(int index, int testId, int user1, int user2, int user3) { + mTests[index] = new ScriptField_TestScripts_s.Item(); + mTests[index].testScript = mUiScript; + mTests[index].testName = Allocation.createFromString(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + mTests[index].debugName = RsBenchRS.createZeroTerminatedAlloc(mRS, + mNames[index], + Allocation.USAGE_SCRIPT); + + ScriptField_UiTestData_s.Item dataItem = new ScriptField_UiTestData_s.Item(); + dataItem.testId = testId; + dataItem.user1 = user1; + dataItem.user2 = user2; + dataItem.user3 = user3; + ScriptField_UiTestData_s testData = new ScriptField_UiTestData_s(mRS, 1); + testData.set(dataItem, 0, true); + mTests[index].testData = testData.getAllocation(); + } + + public boolean init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8); + mSingleMesh = getSingleMesh(1, 1); // a unit size mesh + + initUiScript(); + mTests = new ScriptField_TestScripts_s.Item[mNames.length]; + + int index = 0; + + addTest(index++, 0, 0 /*meshMode*/, 0 /*unused*/, 0 /*unused*/); + addTest(index++, 0, 1 /*meshMode*/, 0 /*unused*/, 0 /*unused*/); + addTest(index++, 1, 7 /*wResolution*/, 5 /*hResolution*/, 0 /*meshMode*/); + addTest(index++, 1, 7 /*wResolution*/, 5 /*hResolution*/, 1 /*meshMode*/); + addTest(index++, 2, 0 /*unused*/, 0 /*unused*/, 0 /*unused*/); + addTest(index++, 3, 7 /*wResolution*/, 5 /*hResolution*/, 0 /*unused*/); + + return true; + } + + public ScriptField_TestScripts_s.Item[] getTests() { + return mTests; + } + + public String[] getTestNames() { + return mNames; + } + + private Allocation loadTextureRGB(int id) { + return Allocation.createFromBitmapResource(mRS, mRes, id, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + private Allocation loadTextureARGB(int id) { + Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); + return Allocation.createFromBitmap(mRS, b, + Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + } + + private void createParticlesMesh() { + ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT); + + final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS); + meshBuilder.addVertexAllocation(p.getAllocation()); + final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex(); + meshBuilder.addIndexSetType(Primitive.POINT); + mParticlesMesh = meshBuilder.create(); + + mUiScript.set_gParticlesMesh(mParticlesMesh); + mUiScript.bind_Particles(p); + } + + /** + * Create a mesh with a single quad for the given width and height. + */ + private Mesh getSingleMesh(float width, float height) { + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, + 2, Mesh.TriangleMeshBuilder.TEXTURE_0); + float xOffset = width/2; + float yOffset = height/2; + tmb.setTexture(0, 0); + tmb.addVertex(-1.0f * xOffset, -1.0f * yOffset); + tmb.setTexture(1, 0); + tmb.addVertex(xOffset, -1.0f * yOffset); + tmb.setTexture(1, 1); + tmb.addVertex(xOffset, yOffset); + tmb.setTexture(0, 1); + tmb.addVertex(-1.0f * xOffset, yOffset); + tmb.addTriangle(0, 3, 1); + tmb.addTriangle(1, 3, 2); + return tmb.create(true); + } + + private Matrix4f getProjectionNormalized(int w, int h) { + // range -1,1 in the narrow axis at z = 0. + Matrix4f m1 = new Matrix4f(); + Matrix4f m2 = new Matrix4f(); + + if(w > h) { + float aspect = ((float)w) / h; + m1.loadFrustum(-aspect,aspect, -1,1, 1,100); + } else { + float aspect = ((float)h) / w; + m1.loadFrustum(-1,1, -aspect,aspect, 1,100); + } + + m2.loadRotate(180, 0, 1, 0); + m1.loadMultiply(m1, m2); + + m2.loadScale(-2, 2, 1); + m1.loadMultiply(m1, m2); + + m2.loadTranslate(0, 0, 2); + m1.loadMultiply(m1, m2); + return m1; + } + + private void updateProjectionMatrices() { + Matrix4f projNorm = getProjectionNormalized(1280, 720); + ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item(); + i.Proj = projNorm; + i.MVP = projNorm; + mPvStarAlloc.set(i, 0, true); + mPvProjectionAlloc.setProjection(projNorm); + } + + void initUiScript() { + mUiScript = new ScriptC_ui_test(mRS, mRes, R.raw.ui_test); + + ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS); + colBuilder.setVaryingColor(false); + ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS); + texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertexFixedFunction progVertex = pvb.create(); + ProgramVertexFixedFunction.Constants PVA = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)progVertex).bindConstants(PVA); + Matrix4f proj = new Matrix4f(); + proj.loadOrthoWindow(1280, 720); + PVA.setProjection(proj); + + mUiScript.set_gProgVertex(progVertex); + mUiScript.set_gProgFragmentColor(colBuilder.create()); + mUiScript.set_gProgFragmentTexture(texBuilder.create()); + mUiScript.set_gProgStoreBlendAlpha(ProgramStore.BLEND_ALPHA_DEPTH_NONE(mRS)); + + mUiScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); + + mUiScript.set_gTexTorus(loadTextureRGB(R.drawable.torusmap)); + mUiScript.set_gTexOpaque(loadTextureRGB(R.drawable.data)); + mUiScript.set_gTexGlobe(loadTextureRGB(R.drawable.globe)); + mUiScript.set_gSingleMesh(mSingleMesh); + + // For GALAXY + ProgramStore.Builder psb = new ProgramStore.Builder(mRS); + psb.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); + mRS.bindProgramStore(psb.create()); + + psb.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE); + mUiScript.set_gPSLights(psb.create()); + + // For Galaxy live wallpaper drawing + ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGB, 0); + ProgramFragment pfb = builder.create(); + pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0); + mUiScript.set_gPFBackground(pfb); + + builder = new ProgramFragmentFixedFunction.Builder(mRS); + builder.setPointSpriteTexCoordinateReplacement(true); + builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + builder.setVaryingColor(true); + ProgramFragment pfs = builder.create(); + pfs.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); + mUiScript.set_gPFStars(pfs); + + mTextureAllocs = new ScriptField_ListAllocs_s(mRS, 100); + for (int i = 0; i < 100; i++) { + ScriptField_ListAllocs_s.Item texElem = new ScriptField_ListAllocs_s.Item(); + texElem.item = loadTextureRGB(R.drawable.globe); + mTextureAllocs.set(texElem, i, false); + } + mTextureAllocs.copyAll(); + mUiScript.bind_gTexList100(mTextureAllocs); + + mSampleTextAllocs = new ScriptField_ListAllocs_s(mRS, 100); + for (int i = 0; i < 100; i++) { + ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); + textElem.item = Allocation.createFromString(mRS, SAMPLE_TEXT, Allocation.USAGE_SCRIPT); + mSampleTextAllocs.set(textElem, i, false); + } + mSampleTextAllocs.copyAll(); + mUiScript.bind_gSampleTextList100(mSampleTextAllocs); + + mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000); + for (int i = 0; i < 1000; i++) { + ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item(); + textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT); + mSampleListViewAllocs.set(textElem, i, false); + } + mSampleListViewAllocs.copyAll(); + mUiScript.bind_gListViewText(mSampleListViewAllocs); + + // For galaxy live wallpaper + mPvStarAlloc = new ScriptField_VpConsts(mRS, 1); + mUiScript.bind_vpConstants(mPvStarAlloc); + mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS); + updateProjectionMatrices(); + + pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertex pvbp = pvb.create(); + ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc); + mUiScript.set_gPVBkProj(pvbp); + + createParticlesMesh(); + + ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS); + String t = "varying vec4 varColor;\n" + + "varying vec2 varTex0;\n" + + "void main() {\n" + + " float dist = ATTRIB_position.y;\n" + + " float angle = ATTRIB_position.x;\n" + + " float x = dist * sin(angle);\n" + + " float y = dist * cos(angle) * 0.892;\n" + + " float p = dist * 5.5;\n" + + " float s = cos(p);\n" + + " float t = sin(p);\n" + + " vec4 pos;\n" + + " pos.x = t * x + s * y;\n" + + " pos.y = s * x - t * y;\n" + + " pos.z = ATTRIB_position.z;\n" + + " pos.w = 1.0;\n" + + " gl_Position = UNI_MVP * pos;\n" + + " gl_PointSize = ATTRIB_color.a * 10.0;\n" + + " varColor.rgb = ATTRIB_color.rgb;\n" + + " varColor.a = 1.0;\n" + + "}\n"; + sb.setShader(t); + sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement()); + sb.addConstant(mPvStarAlloc.getType()); + ProgramVertex pvs = sb.create(); + pvs.bindConstants(mPvStarAlloc.getAllocation(), 0); + mUiScript.set_gPVStars(pvs); + + // For Galaxy live wallpaper + mUiScript.set_gTSpace(loadTextureRGB(R.drawable.space)); + mUiScript.set_gTLight1(loadTextureRGB(R.drawable.light1)); + mUiScript.set_gTFlares(loadTextureARGB(R.drawable.flares)); + + mUiScript.set_gFontSans(mFontSans); + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs new file mode 100644 index 0000000..281f830 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs @@ -0,0 +1,158 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.perftest) + +#include "rs_graphics.rsh" +#include "subtest_def.rsh" + +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentTexture; +rs_program_fragment gProgFragmentTextureModulate; +rs_program_fragment gProgFragmentMultitex; + +rs_program_store gProgStoreBlendNone; +rs_program_store gProgStoreBlendAlpha; + +rs_allocation gTexOpaque; +rs_allocation gTexTorus; +rs_allocation gTexTransparent; +rs_allocation gTexChecker; + +rs_sampler gLinearClamp; +rs_sampler gLinearWrap; + +typedef struct FillTestData_s { + int testId; + int blend; + int quadCount; +} FillTestData; +FillTestData *gData; + +typedef struct FillTestFragData_s { + float4 modulate; +} FillTestFragData; +FillTestFragData *gFragData; + +static float gDt = 0.0f; + +void init() { +} + +static int gRenderSurfaceW = 1280; +static int gRenderSurfaceH = 720; + +static void bindProgramVertexOrtho() { + // Default vertex shader + rsgBindProgramVertex(gProgVertex); + // Setup the projection matrix + rs_matrix4x4 proj; + rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); +} + +static void displaySingletexFill(bool blend, int quadCount, bool modulate) { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + if (!blend) { + rsgBindProgramStore(gProgStoreBlendNone); + } else { + rsgBindProgramStore(gProgStoreBlendAlpha); + } + if (modulate) { + rsgBindProgramFragment(gProgFragmentTextureModulate); + rsgBindSampler(gProgFragmentTextureModulate, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTextureModulate, 0, gTexOpaque); + + gFragData->modulate.r = 0.8f; + gFragData->modulate.g = 0.7f; + gFragData->modulate.b = 0.8f; + gFragData->modulate.a = 0.5f; + rsgAllocationSyncAll(rsGetAllocation(gFragData)); + } else { + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + } + + for (int i = 0; i < quadCount; i ++) { + float startX = 5 * i, startY = 5 * i; + float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + } +} + +static void displayMultitextureSample(bool blend, int quadCount) { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + if (!blend) { + rsgBindProgramStore(gProgStoreBlendNone); + } else { + rsgBindProgramStore(gProgStoreBlendAlpha); + } + rsgBindProgramFragment(gProgFragmentMultitex); + rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp); + rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap); + rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp); + rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker); + rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus); + rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent); + + for (int i = 0; i < quadCount; i ++) { + float startX = 10 * i, startY = 10 * i; + float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + } +} + + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + TestData *testData = (TestData*)usrData; + gRenderSurfaceW = testData->renderSurfaceW; + gRenderSurfaceH = testData->renderSurfaceH; + gDt = testData->dt; + + gData = (FillTestData*)v_in; + + switch(gData->testId) { + case 0: + displayMultitextureSample(gData->blend == 1 ? true : false, gData->quadCount); + break; + case 1: + displaySingletexFill(gData->blend == 1 ? true : false, gData->quadCount, false); + break; + case 2: + displaySingletexFill(gData->blend == 1 ? true : false, gData->quadCount, true); + break; + default: + rsDebug("Wrong test number", 0); + break; + } +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/mesh_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/mesh_test.rs new file mode 100644 index 0000000..d7e4857 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/mesh_test.rs @@ -0,0 +1,89 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.perftest) + +#include "rs_graphics.rsh" +#include "shader_def.rsh" +#include "subtest_def.rsh" + +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentTexture; + +rs_program_store gProgStoreBlendNone; + +rs_allocation gTexOpaque; + +rs_mesh g10by10Mesh; +rs_mesh g100by100Mesh; +rs_mesh gWbyHMesh; + +rs_sampler gLinearClamp; +static int gRenderSurfaceW; +static int gRenderSurfaceH; + +static float gDt = 0; + +typedef struct MeshTestData_s { + int meshNum; +} MeshTestData; +MeshTestData *gData; + +void init() { +} + +static void bindProgramVertexOrtho() { + // Default vertex shader + rsgBindProgramVertex(gProgVertex); + // Setup the projection matrix + rs_matrix4x4 proj; + rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); +} + +static void displayMeshSamples(int meshNum) { + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, gRenderSurfaceW/2, gRenderSurfaceH/2, 0); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + if (meshNum == 0) { + rsgDrawMesh(g10by10Mesh); + } else if (meshNum == 1) { + rsgDrawMesh(g100by100Mesh); + } else if (meshNum == 2) { + rsgDrawMesh(gWbyHMesh); + } +} + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + TestData *testData = (TestData*)usrData; + gRenderSurfaceW = testData->renderSurfaceW; + gRenderSurfaceH = testData->renderSurfaceH; + gDt = testData->dt; + + gData = (MeshTestData*)v_in; + + displayMeshSamples(gData->meshNum); +} diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs index db97835..27e5b11 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs @@ -1,4 +1,4 @@ -// Copyright (C) 2009 The Android Open Source Project +// Copyright (C) 2010-2011 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,104 +24,34 @@ const int RS_MSG_TEST_DONE = 100; const int RS_MSG_RESULTS_READY = 101; -const int gMaxModes = 31; -int gMaxLoops; - -// Parameters for galaxy live wallpaper -rs_allocation gTSpace; -rs_allocation gTLight1; -rs_allocation gTFlares; -rs_mesh gParticlesMesh; - -rs_program_fragment gPFBackground; -rs_program_fragment gPFStars; -rs_program_vertex gPVStars; -rs_program_vertex gPVBkProj; -rs_program_store gPSLights; - -float gXOffset = 0.5f; - -#define ELLIPSE_RATIO 0.892f -#define PI 3.1415f -#define TWO_PI 6.283f -#define ELLIPSE_TWIST 0.023333333f - -static float angle = 50.f; -static int gOldWidth; -static int gOldHeight; -static int gWidth; -static int gHeight; -static float gSpeed[12000]; -static int gGalaxyRadius = 300; -static rs_allocation gParticlesBuffer; - -typedef struct __attribute__((packed, aligned(4))) Particle { - uchar4 color; - float3 position; -} Particle_t; -Particle_t *Particles; - -typedef struct VpConsts { - rs_matrix4x4 Proj; - rs_matrix4x4 MVP; -} VpConsts_t; -VpConsts_t *vpConstants; -// End of parameters for galaxy live wallpaper - -// Allocation to send test names back to java -char *gStringBuffer = 0; +static const int gMaxModes = 64; +int gMaxLoops = 1; +int gDisplayMode = 1; + // Allocation to write the results into static float gResultBuffer[gMaxModes]; -rs_program_vertex gProgVertex; -rs_program_fragment gProgFragmentColor; -rs_program_fragment gProgFragmentTexture; - -rs_program_store gProgStoreBlendNoneDepth; -rs_program_store gProgStoreBlendNone; -rs_program_store gProgStoreBlendAlpha; -rs_program_store gProgStoreBlendAdd; - -rs_allocation gTexOpaque; -rs_allocation gTexTorus; -rs_allocation gTexTransparent; -rs_allocation gTexChecker; -rs_allocation gTexGlobe; - -typedef struct ListAllocs_s { - rs_allocation item; -} ListAllocs; - -ListAllocs *gTexList100; -ListAllocs *gSampleTextList100; -ListAllocs *gListViewText; - -rs_mesh g10by10Mesh; -rs_mesh g100by100Mesh; -rs_mesh gWbyHMesh; -rs_mesh gSingleMesh; - -rs_font gFontSans; rs_font gFontSerif; - -int gDisplayMode; - rs_sampler gLinearClamp; -rs_sampler gLinearWrap; -rs_sampler gMipLinearWrap; -rs_sampler gNearestClamp; -rs_program_raster gCullBack; -rs_program_raster gCullFront; -rs_program_raster gCullNone; +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentTexture; + +rs_allocation gRenderBufferColor; +rs_allocation gRenderBufferDepth; -// Export these out to easily set the inputs to shader VertexShaderInputs *gVSInputs; -rs_program_fragment gProgFragmentMultitex; +typedef struct TestScripts_s { + rs_allocation testData; + rs_allocation testName; + rs_allocation debugName; + rs_script testScript; +} TestScripts; +TestScripts *gTestScripts; -rs_allocation gRenderBufferColor; -rs_allocation gRenderBufferDepth; +bool gLoadComplete = false; +bool gPauseRendering = false; static float gDt = 0; @@ -131,158 +61,17 @@ void init() { static int gRenderSurfaceW; static int gRenderSurfaceH; -/** - * Methods to draw the galaxy live wall paper - */ -static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) { - return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart)); -} - -/** - * Helper function to generate the stars. - */ -static float randomGauss() { - float x1; - float x2; - float w = 2.f; - - while (w >= 1.0f) { - x1 = rsRand(2.0f) - 1.0f; - x2 = rsRand(2.0f) - 1.0f; - w = x1 * x1 + x2 * x2; - } - - w = sqrt(-2.0f * log(w) / w); - return x1 * w; +static void fillSurfaceParams(TestData *testData) { + testData->renderSurfaceW = gRenderSurfaceW; + testData->renderSurfaceH = gRenderSurfaceH; + testData->dt = gDt; } -/** - * Generates the properties for a given star. - */ -static void createParticle(Particle_t *part, int idx, float scale) { - float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f); - float id = d / gGalaxyRadius; - float z = randomGauss() * 0.4f * (1.0f - id); - float p = -d * ELLIPSE_TWIST; - - if (d < gGalaxyRadius * 0.33f) { - part->color.x = (uchar) (220 + id * 35); - part->color.y = 220; - part->color.z = 220; - } else { - part->color.x = 180; - part->color.y = 180; - part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f); - } - // Stash point size * 10 in Alpha - part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60); - - if (d > gGalaxyRadius * 0.15f) { - z *= 0.6f * (1.0f - id); - } else { - z *= 0.72f; - } - - // Map to the projection coordinates (viewport.x = -1.0 -> 1.0) - d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d); - - part->position.x = rsRand(TWO_PI); - part->position.y = d; - gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f; - - part->position.z = z / 5.0f; -} - -/** - * Initialize all the starts, called from Java - */ -void initParticles() { - Particle_t *part = Particles; - float scale = gGalaxyRadius / (gWidth * 0.5f); - int count = rsAllocationGetDimX(gParticlesBuffer); - for (int i = 0; i < count; i ++) { - createParticle(part, i, scale); - part++; - } -} - -static void drawSpace() { - rsgBindProgramFragment(gPFBackground); - rsgBindTexture(gPFBackground, 0, gTSpace); - rsgDrawQuadTexCoords( - 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - gWidth, 0.0f, 0.0f, 2.0f, 1.0f, - gWidth, gHeight, 0.0f, 2.0f, 0.0f, - 0.0f, gHeight, 0.0f, 0.0f, 0.0f); -} - -static void drawLights() { - rsgBindProgramVertex(gPVBkProj); - rsgBindProgramFragment(gPFBackground); - rsgBindTexture(gPFBackground, 0, gTLight1); - - float scale = 512.0f / gWidth; - float x = -scale - scale * 0.05f; - float y = -scale; - - scale *= 2.0f; - - rsgDrawQuad(x, y, 0.0f, - x + scale * 1.1f, y, 0.0f, - x + scale * 1.1f, y + scale, 0.0f, - x, y + scale, 0.0f); -} - -static void drawParticles(float offset) { - float a = offset * angle; - float absoluteAngle = fabs(a); - - rs_matrix4x4 matrix; - rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f); - if (gHeight > gWidth) { - rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f); - } else { - rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f); - } - rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f); - rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f); - rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj); - rsMatrixMultiply(&vpConstants->MVP, &matrix); - rsgAllocationSyncAll(rsGetAllocation(vpConstants)); - - rsgBindProgramVertex(gPVStars); - rsgBindProgramFragment(gPFStars); - rsgBindProgramStore(gPSLights); - rsgBindTexture(gPFStars, 0, gTFlares); - - Particle_t *vtx = Particles; - int count = rsAllocationGetDimX(gParticlesBuffer); - for (int i = 0; i < count; i++) { - vtx->position.x = vtx->position.x + gSpeed[i]; - vtx++; - } - - rsgDrawMesh(gParticlesMesh); -} -/* end of methods for drawing galaxy */ - static void setupOffscreenTarget() { rsgBindColorTarget(gRenderBufferColor, 0); rsgBindDepthTarget(gRenderBufferDepth); } -rs_script gFontScript; -rs_script gTorusScript; -rs_allocation gDummyAlloc; - -static void displayFontSamples(int fillNum) { - TestData testData; - testData.renderSurfaceW = gRenderSurfaceW; - testData.renderSurfaceH = gRenderSurfaceH; - testData.user = fillNum; - rsForEach(gFontScript, gDummyAlloc, gDummyAlloc, &testData, sizeof(testData)); -} - static void bindProgramVertexOrtho() { // Default vertex shader rsgBindProgramVertex(gProgVertex); @@ -292,302 +81,31 @@ static void bindProgramVertexOrtho() { rsgProgramVertexLoadProjectionMatrix(&proj); } -static void displaySingletexFill(bool blend, int quadCount) { - bindProgramVertexOrtho(); - rs_matrix4x4 matrix; - rsMatrixLoadIdentity(&matrix); - rsgProgramVertexLoadModelMatrix(&matrix); - - // Fragment shader with texture - if (!blend) { - rsgBindProgramStore(gProgStoreBlendNone); - } else { - rsgBindProgramStore(gProgStoreBlendAlpha); - } - rsgBindProgramFragment(gProgFragmentTexture); - rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); - rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); - - for (int i = 0; i < quadCount; i ++) { - float startX = 5 * i, startY = 5 * i; - float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY; - rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, - startX, startY + height, 0, 0, 1, - startX + width, startY + height, 0, 1, 1, - startX + width, startY, 0, 1, 0); - } -} - -static void displayMeshSamples(int meshNum) { - - bindProgramVertexOrtho(); - rs_matrix4x4 matrix; - rsMatrixLoadTranslate(&matrix, gRenderSurfaceW/2, gRenderSurfaceH/2, 0); - rsgProgramVertexLoadModelMatrix(&matrix); - - // Fragment shader with texture - rsgBindProgramStore(gProgStoreBlendNone); - rsgBindProgramFragment(gProgFragmentTexture); - rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); - - rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); - - if (meshNum == 0) { - rsgDrawMesh(g10by10Mesh); - } else if (meshNum == 1) { - rsgDrawMesh(g100by100Mesh); - } else if (meshNum == 2) { - rsgDrawMesh(gWbyHMesh); - } -} - -// Display sample images in a mesh with different texture -static void displayIcons(int meshMode) { - bindProgramVertexOrtho(); - - // Fragment shader with texture - rsgBindProgramStore(gProgStoreBlendAlpha); - rsgBindProgramFragment(gProgFragmentTexture); - rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); - rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); - rsgDrawQuadTexCoords( - 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, gRenderSurfaceH, 0.0f, 0.0f, 1.0f, - gRenderSurfaceW, gRenderSurfaceH, 0.0f, 1.0f, 1.0f, - gRenderSurfaceW, 0.0f, 0.0f, 1.0f, 0.0f); - - int meshCount = (int)pow(10.0f, (float)(meshMode + 1)); - - float wSize = gRenderSurfaceW/(float)meshCount; - float hSize = gRenderSurfaceH/(float)meshCount; - rs_matrix4x4 matrix; - rsMatrixLoadScale(&matrix, wSize, hSize, 1.0); - - float yPos = 0; - float yPad = hSize / 2; - float xPad = wSize / 2; - for (int y = 0; y < meshCount; y++) { - yPos = y * hSize + yPad; - float xPos = 0; - for (int x = 0; x < meshCount; x++) { - xPos = x * wSize + xPad; - rs_matrix4x4 transMatrix; - rsMatrixLoadTranslate(&transMatrix, xPos, yPos, 0); - rsMatrixMultiply(&transMatrix, &matrix); - rsgProgramVertexLoadModelMatrix(&transMatrix); - int i = (x + y * meshCount) % 100; - rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item); - rsgDrawMesh(gSingleMesh); - } - } -} - -// Draw meshes in a single page with top left corner coordinates (xStart, yStart) -static void drawMeshInPage(float xStart, float yStart, int wResolution, int hResolution) { - // Draw wResolution * hResolution meshes in one page - float wMargin = 100.0f; - float hMargin = 100.0f; - float xPad = 50.0f; - float yPad = 20.0f; - float size = 100.0f; // size of images - - // font info - rs_font font = gFontSans; - rsgBindFont(font); - rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); - - // Measure text size - int left = 0, right = 0, top = 0, bottom = 0; - rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom); - float textHeight = (float)(top - bottom); - float textWidth = (float)(right - left); - - rs_matrix4x4 matrix; - rsMatrixLoadScale(&matrix, size, size, 1.0); - - for (int y = 0; y < hResolution; y++) { - float yPos = yStart + hMargin + y * size + y * yPad; - for (int x = 0; x < wResolution; x++) { - float xPos = xStart + wMargin + x * size + x * xPad; - - rs_matrix4x4 transMatrix; - rsMatrixLoadTranslate(&transMatrix, xPos + size/2, yPos + size/2, 0); - rsMatrixMultiply(&transMatrix, &matrix); // scale the mesh - rsgProgramVertexLoadModelMatrix(&transMatrix); - - int i = (y * wResolution + x) % 100; - rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item); - rsgDrawMesh(gSingleMesh); - rsgDrawText(gSampleTextList100[i].item, xPos, yPos + size + yPad/2 + textHeight); - } - } -} - -// Display both images and text as shown in launcher and homepage -// meshMode will decide how many pages we draw -// meshMode = 0: draw 3 pages of meshes -// meshMode = 1: draw 5 pages of meshes -static void displayImageWithText(int wResolution, int hResolution, int meshMode) { - bindProgramVertexOrtho(); - - // Fragment shader with texture - rsgBindProgramStore(gProgStoreBlendAlpha); - rsgBindProgramFragment(gProgFragmentTexture); - rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); - - drawMeshInPage(0, 0, wResolution, hResolution); - drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); - drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); - if (meshMode == 1) { - // draw another two pages of meshes - drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); - drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); - } -} - -// Display a list of text as the list view -static void displayListView() { - // set text color - rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); - rsgBindFont(gFontSans); - - // get the size of the list - rs_allocation textAlloc; - textAlloc = rsGetAllocation(gListViewText); - int allocSize = rsAllocationGetDimX(textAlloc); - - int listItemHeight = 80; - int yOffset = listItemHeight; - - // set the color for the list divider - rsgBindProgramFragment(gProgFragmentColor); - rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1); - - // draw the list with divider - for (int i = 0; i < allocSize; i++) { - if (yOffset - listItemHeight > gRenderSurfaceH) { - break; - } - rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0); - rsgDrawText(gListViewText[i].item, 20, yOffset - 10); - yOffset += listItemHeight; - } -} - -static void drawGalaxy() { - rsgClearColor(0.f, 0.f, 0.f, 1.f); - gParticlesBuffer = rsGetAllocation(Particles); - rsgBindProgramFragment(gPFBackground); - - gWidth = rsgGetWidth(); - gHeight = rsgGetHeight(); - if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) { - initParticles(); - gOldWidth = gWidth; - gOldHeight = gHeight; - } - - float offset = mix(-1.0f, 1.0f, gXOffset); - drawSpace(); - drawParticles(offset); - drawLights(); -} - -// Display images and text with live wallpaper in the background -static void displayLiveWallPaper(int wResolution, int hResolution) { - bindProgramVertexOrtho(); - - drawGalaxy(); - - rsgBindProgramVertex(gProgVertex); - rsgBindProgramStore(gProgStoreBlendAlpha); - rsgBindProgramFragment(gProgFragmentTexture); - rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); - - drawMeshInPage(0, 0, wResolution, hResolution); - drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); - drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); - drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); - drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); -} - -// Quick hack to get some geometry numbers -static void displaySimpleGeoSamples(bool useTexture, int numMeshes) { +static void runSubTest(int index) { TestData testData; - testData.renderSurfaceW = gRenderSurfaceW; - testData.renderSurfaceH = gRenderSurfaceH; - testData.dt = gDt; - testData.user = 0; - testData.user1 = useTexture ? 1 : 0; - testData.user2 = numMeshes; - rsForEach(gTorusScript, gDummyAlloc, gDummyAlloc, &testData, sizeof(testData)); -} + fillSurfaceParams(&testData); -static void displayCustomShaderSamples(int numMeshes) { - TestData testData; - testData.renderSurfaceW = gRenderSurfaceW; - testData.renderSurfaceH = gRenderSurfaceH; - testData.dt = gDt; - testData.user = 1; - testData.user1 = numMeshes; - rsForEach(gTorusScript, gDummyAlloc, gDummyAlloc, &testData, sizeof(testData)); + rs_allocation null_alloc; + rsForEach(gTestScripts[index].testScript, + gTestScripts[index].testData, + null_alloc, + &testData, + sizeof(testData)); } -static void displayPixelLightSamples(int numMeshes, bool heavyVertex) { - TestData testData; - testData.renderSurfaceW = gRenderSurfaceW; - testData.renderSurfaceH = gRenderSurfaceH; - testData.dt = gDt; - testData.user = 2; - testData.user1 = numMeshes; - testData.user2 = heavyVertex ? 1 : 0; - rsForEach(gTorusScript, gDummyAlloc, gDummyAlloc, &testData, sizeof(testData)); -} - -static void displayMultitextureSample(bool blend, int quadCount) { - bindProgramVertexOrtho(); - rs_matrix4x4 matrix; - rsMatrixLoadIdentity(&matrix); - rsgProgramVertexLoadModelMatrix(&matrix); - - // Fragment shader with texture - if (!blend) { - rsgBindProgramStore(gProgStoreBlendNone); - } else { - rsgBindProgramStore(gProgStoreBlendAlpha); - } - rsgBindProgramFragment(gProgFragmentMultitex); - rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp); - rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap); - rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp); - rsgBindTexture(gProgFragmentMultitex, 0, gTexChecker); - rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus); - rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent); - - for (int i = 0; i < quadCount; i ++) { - float startX = 10 * i, startY = 10 * i; - float width = gRenderSurfaceW - startX, height = gRenderSurfaceH - startY; - rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, - startX, startY + height, 0, 0, 1, - startX + width, startY + height, 0, 1, 1, - startX + width, startY, 0, 1, 0); - } -} static bool checkInit() { - static int countdown = 5; + static int countdown = 3; // Perform all the uploads so we only measure rendered time if(countdown > 1) { - displayFontSamples(5); - displaySingletexFill(true, 3); - displayMeshSamples(0); - displayMeshSamples(1); - displayMeshSamples(2); - displayMultitextureSample(true, 5); - displayPixelLightSamples(1, false); - displayPixelLightSamples(1, true); + int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts)); + for(int i = 0; i < testCount; i ++) { + rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f); + runSubTest(i); + rsgFinish(); + } countdown --; rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f); @@ -606,43 +124,11 @@ static bool checkInit() { } static int benchMode = 0; +static bool benchmarkSingleTest = false; +static int benchSubMode = 0; static int runningLoops = 0; static bool sendMsgFlag = false; -static const char *testNames[] = { - "Fill screen with text 1 time", - "Fill screen with text 3 times", - "Fill screen with text 5 times", - "Geo test 25.6k flat color", - "Geo test 51.2k flat color", - "Geo test 204.8k small tries flat color", - "Geo test 25.6k single texture", - "Geo test 51.2k single texture", - "Geo test 204.8k small tries single texture", - "Full screen mesh 10 by 10", - "Full screen mesh 100 by 100", - "Full screen mesh W / 4 by H / 4", - "Geo test 25.6k geo heavy vertex", - "Geo test 51.2k geo heavy vertex", - "Geo test 204.8k geo raster load heavy vertex", - "Fill screen 10x singletexture", - "Fill screen 10x 3tex multitexture", - "Fill screen 10x blended singletexture", - "Fill screen 10x blended 3tex multitexture", - "Geo test 25.6k heavy fragment", - "Geo test 51.2k heavy fragment", - "Geo test 204.8k small tries heavy fragment", - "Geo test 25.6k heavy fragment heavy vertex", - "Geo test 51.2k heavy fragment heavy vertex", - "Geo test 204.8k small tries heavy fragment heavy vertex", - "UI test with icon display 10 by 10", - "UI test with icon display 100 by 100", - "UI test with image and text display 3 pages", - "UI test with image and text display 5 pages", - "UI test with list view", - "UI test with live wallpaper", -}; - static bool gIsDebugMode = false; void setDebugMode(int testNumber) { gIsDebugMode = true; @@ -650,122 +136,17 @@ void setDebugMode(int testNumber) { rsgClearAllRenderTargets(); } -void setBenchmarkMode() { +void setBenchmarkMode(int testNumber) { gIsDebugMode = false; - benchMode = 0; - runningLoops = 0; -} - - -void getTestName(int testIndex) { - int bufferLen = rsAllocationGetDimX(rsGetAllocation(gStringBuffer)); - if (testIndex >= gMaxModes) { - return; - } - uint charIndex = 0; - while (testNames[testIndex][charIndex] != '\0' && charIndex < bufferLen) { - gStringBuffer[charIndex] = testNames[testIndex][charIndex]; - charIndex ++; + if (testNumber == -1) { + benchmarkSingleTest = false; + benchMode = 0; + } else { + benchmarkSingleTest = true; + benchMode = testNumber; } - gStringBuffer[charIndex] = '\0'; -} -static void runTest(int index) { - switch (index) { - case 0: - displayFontSamples(1); - break; - case 1: - displayFontSamples(3); - break; - case 2: - displayFontSamples(5); - break; - case 3: - displaySimpleGeoSamples(false, 1); - break; - case 4: - displaySimpleGeoSamples(false, 2); - break; - case 5: - displaySimpleGeoSamples(false, 8); - break; - case 6: - displaySimpleGeoSamples(true, 1); - break; - case 7: - displaySimpleGeoSamples(true, 2); - break; - case 8: - displaySimpleGeoSamples(true, 8); - break; - case 9: - displayMeshSamples(0); - break; - case 10: - displayMeshSamples(1); - break; - case 11: - displayMeshSamples(2); - break; - case 12: - displayCustomShaderSamples(1); - break; - case 13: - displayCustomShaderSamples(2); - break; - case 14: - displayCustomShaderSamples(10); - break; - case 15: - displaySingletexFill(false, 10); - break; - case 16: - displayMultitextureSample(false, 10); - break; - case 17: - displaySingletexFill(true, 10); - break; - case 18: - displayMultitextureSample(true, 10); - break; - case 19: - displayPixelLightSamples(1, false); - break; - case 20: - displayPixelLightSamples(2, false); - break; - case 21: - displayPixelLightSamples(8, false); - break; - case 22: - displayPixelLightSamples(1, true); - break; - case 23: - displayPixelLightSamples(2, true); - break; - case 24: - displayPixelLightSamples(8, true); - break; - case 25: - displayIcons(0); - break; - case 26: - displayIcons(1); - break; - case 27: - displayImageWithText(7, 5, 0); - break; - case 28: - displayImageWithText(7, 5, 1); - break; - case 29: - displayListView(); - break; - case 30: - displayLiveWallPaper(7, 5); - break; - } + runningLoops = 0; } static void drawOffscreenResult(int posX, int posY, int width, int height) { @@ -803,7 +184,7 @@ static void benchmark() { rsgClearColor(0.1f, 0.1f, 0.1f, 1.0f); rsgClearDepth(1.0f); - runTest(benchMode); + runSubTest(benchMode); rsgClearAllRenderTargets(); gRenderSurfaceW = rsgGetWidth(); gRenderSurfaceH = rsgGetHeight(); @@ -816,25 +197,34 @@ static void benchmark() { int64_t end = rsUptimeMillis(); float fps = (float)(frameCount) / ((float)(end - start)*0.001f); - rsDebug(testNames[benchMode], fps); + const char *testName = rsGetElementAt(gTestScripts[benchMode].debugName, 0); + rsDebug(testName, fps); + gResultBuffer[benchMode] = fps; - drawOffscreenResult(0, 0, - gRenderSurfaceW / 2, - gRenderSurfaceH / 2); - const char* text = testNames[benchMode]; + int bufferW = rsAllocationGetDimX(gRenderBufferColor); + int bufferH = rsAllocationGetDimY(gRenderBufferColor); + + int quadW = gRenderSurfaceW / 2; + int quadH = (quadW * bufferH) / bufferW; + drawOffscreenResult(0, 0, quadW, quadH); + int left = 0, right = 0, top = 0, bottom = 0; uint width = rsgGetWidth(); uint height = rsgGetHeight(); rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f); rsgBindFont(gFontSerif); - rsgMeasureText(text, &left, &right, &top, &bottom); + rsgMeasureText(gTestScripts[benchMode].testName, &left, &right, &top, &bottom); rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); - rsgDrawText(text, 2 -left, height - 2 + bottom); + rsgDrawText(gTestScripts[benchMode].testName, 2 -left, height - 2 + bottom); - benchMode ++; + if (benchmarkSingleTest) { + return; + } - if (benchMode == gMaxModes) { - rsSendToClientBlocking(RS_MSG_RESULTS_READY, gResultBuffer, gMaxModes*sizeof(float)); + benchMode ++; + int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts)); + if (benchMode == testCount) { + rsSendToClientBlocking(RS_MSG_RESULTS_READY, gResultBuffer, testCount*sizeof(float)); benchMode = 0; runningLoops++; if ((gMaxLoops > 0) && (runningLoops > gMaxLoops) && !sendMsgFlag) { @@ -844,14 +234,11 @@ static void benchmark() { sendMsgFlag = true; } } - } static void debug() { gDt = rsGetDt(); - - rsgFinish(); - runTest(benchMode); + runSubTest(benchMode); } int root(void) { @@ -859,10 +246,22 @@ int root(void) { gRenderSurfaceH = rsgGetHeight(); rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f); rsgClearDepth(1.0f); + + if (!gLoadComplete) { + rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f); + rsgBindFont(gFontSerif); + rsgDrawText("Loading", 50, 50); + return 0; + } + if(!checkInit()) { return 1; } + if (gPauseRendering) { + rsgDrawText("Paused", 50, 50); + return 30; + } if (gIsDebugMode) { debug(); } else { diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/subtest_def.rsh b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/subtest_def.rsh index b635373..43658b1 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/subtest_def.rsh +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/subtest_def.rsh @@ -20,9 +20,5 @@ typedef struct TestData_s { int renderSurfaceW; int renderSurfaceH; float dt; - int user; - int user1; - int user2; - int user3; } TestData; diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs index 0df6b35..7f10019 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs @@ -22,6 +22,11 @@ rs_font gFontSans; rs_font gFontSerif; +typedef struct TextTestData_s { + int fillNum; +} TextTestData; +TextTestData *gData; + void init() { } @@ -78,5 +83,8 @@ void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32 TestData *testData = (TestData*)usrData; gRenderSurfaceW = testData->renderSurfaceW; gRenderSurfaceH = testData->renderSurfaceH; - displayFontSamples(testData->user); + + gData = (TextTestData*)v_in; + + displayFontSamples(gData->fillNum); } diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/torus_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/torus_test.rs index 26d5680..853a05d 100644 --- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/torus_test.rs +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/torus_test.rs @@ -47,6 +47,13 @@ rs_program_vertex gProgVertexPixelLight; rs_program_vertex gProgVertexPixelLightMove; rs_program_fragment gProgFragmentPixelLight; +typedef struct TorusTestData_s { + int testId; + int user1; + int user2; +} TorusTestData; +TorusTestData *gData; + static float gDt = 0.0f; static int gRenderSurfaceW; @@ -269,15 +276,20 @@ void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32 gRenderSurfaceH = testData->renderSurfaceH; gDt = testData->dt; - switch(testData->user) { + gData = (TorusTestData*)v_in; + + switch(gData->testId) { case 0: - displaySimpleGeoSamples(testData->user1 == 1 ? true : false, testData->user2); + displaySimpleGeoSamples(gData->user1 == 1 ? true : false, gData->user2); break; case 1: - displayCustomShaderSamples(testData->user1); + displayCustomShaderSamples(gData->user1); break; case 2: - displayPixelLightSamples(testData->user1, testData->user2 == 1 ? true : false); + displayPixelLightSamples(gData->user1, gData->user2 == 1 ? true : false); + break; + default: + rsDebug("Wrong test number", gData->testId); break; } } diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs new file mode 100644 index 0000000..5089092 --- /dev/null +++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs @@ -0,0 +1,444 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.perftest) + +#include "rs_graphics.rsh" +#include "shader_def.rsh" +#include "subtest_def.rsh" + +// Parameters for galaxy live wallpaper +rs_allocation gTSpace; +rs_allocation gTLight1; +rs_allocation gTFlares; +rs_mesh gParticlesMesh; + +rs_program_fragment gPFBackground; +rs_program_fragment gPFStars; +rs_program_vertex gPVStars; +rs_program_vertex gPVBkProj; +rs_program_store gPSLights; + +float gXOffset = 0.5f; + +#define ELLIPSE_RATIO 0.892f +#define PI 3.1415f +#define TWO_PI 6.283f +#define ELLIPSE_TWIST 0.023333333f + +static float angle = 50.f; +static int gOldWidth; +static int gOldHeight; +static int gWidth; +static int gHeight; +static float gSpeed[12000]; +static int gGalaxyRadius = 300; +static rs_allocation gParticlesBuffer; + +typedef struct __attribute__((packed, aligned(4))) Particle { + uchar4 color; + float3 position; +} Particle_t; +Particle_t *Particles; + +typedef struct VpConsts { + rs_matrix4x4 Proj; + rs_matrix4x4 MVP; +} VpConsts_t; +VpConsts_t *vpConstants; +// End of parameters for galaxy live wallpaper + +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentColor; +rs_program_fragment gProgFragmentTexture; + +rs_program_store gProgStoreBlendAlpha; + +rs_allocation gTexOpaque; +rs_allocation gTexTorus; +rs_allocation gTexGlobe; + +typedef struct ListAllocs_s { + rs_allocation item; +} ListAllocs; + +ListAllocs *gTexList100; +ListAllocs *gSampleTextList100; +ListAllocs *gListViewText; + +rs_mesh gSingleMesh; + +rs_font gFontSans; + +rs_sampler gLinearClamp; + +typedef struct UiTestData_s { + int testId; + int user1; + int user2; + int user3; +} UiTestData; +UiTestData *gData; + +static float gDt = 0; + + +void init() { +} + +static int gRenderSurfaceW; +static int gRenderSurfaceH; + +static void bindProgramVertexOrtho() { + // Default vertex shader + rsgBindProgramVertex(gProgVertex); + // Setup the projection matrix + rs_matrix4x4 proj; + rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500); + rsgProgramVertexLoadProjectionMatrix(&proj); +} + +/** + * Methods to draw the galaxy live wall paper + */ +static float mapf(float minStart, float minStop, float maxStart, float maxStop, float value) { + return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart)); +} + +/** + * Helper function to generate the stars. + */ +static float randomGauss() { + float x1; + float x2; + float w = 2.f; + + while (w >= 1.0f) { + x1 = rsRand(2.0f) - 1.0f; + x2 = rsRand(2.0f) - 1.0f; + w = x1 * x1 + x2 * x2; + } + + w = sqrt(-2.0f * log(w) / w); + return x1 * w; +} + +/** + * Generates the properties for a given star. + */ +static void createParticle(Particle_t *part, int idx, float scale) { + float d = fabs(randomGauss()) * gGalaxyRadius * 0.5f + rsRand(64.0f); + float id = d / gGalaxyRadius; + float z = randomGauss() * 0.4f * (1.0f - id); + float p = -d * ELLIPSE_TWIST; + + if (d < gGalaxyRadius * 0.33f) { + part->color.x = (uchar) (220 + id * 35); + part->color.y = 220; + part->color.z = 220; + } else { + part->color.x = 180; + part->color.y = 180; + part->color.z = (uchar) clamp(140.f + id * 115.f, 140.f, 255.f); + } + // Stash point size * 10 in Alpha + part->color.w = (uchar) (rsRand(1.2f, 2.1f) * 60); + + if (d > gGalaxyRadius * 0.15f) { + z *= 0.6f * (1.0f - id); + } else { + z *= 0.72f; + } + + // Map to the projection coordinates (viewport.x = -1.0 -> 1.0) + d = mapf(-4.0f, gGalaxyRadius + 4.0f, 0.0f, scale, d); + + part->position.x = rsRand(TWO_PI); + part->position.y = d; + gSpeed[idx] = rsRand(0.0015f, 0.0025f) * (0.5f + (scale / d)) * 0.8f; + + part->position.z = z / 5.0f; +} + +/** + * Initialize all the starts, called from Java + */ +void initParticles() { + Particle_t *part = Particles; + float scale = gGalaxyRadius / (gWidth * 0.5f); + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i ++) { + createParticle(part, i, scale); + part++; + } +} + +static void drawSpace() { + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTSpace); + rsgDrawQuadTexCoords( + 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + gWidth, 0.0f, 0.0f, 2.0f, 1.0f, + gWidth, gHeight, 0.0f, 2.0f, 0.0f, + 0.0f, gHeight, 0.0f, 0.0f, 0.0f); +} + +static void drawLights() { + rsgBindProgramVertex(gPVBkProj); + rsgBindProgramFragment(gPFBackground); + rsgBindTexture(gPFBackground, 0, gTLight1); + + float scale = 512.0f / gWidth; + float x = -scale - scale * 0.05f; + float y = -scale; + + scale *= 2.0f; + + rsgDrawQuad(x, y, 0.0f, + x + scale * 1.1f, y, 0.0f, + x + scale * 1.1f, y + scale, 0.0f, + x, y + scale, 0.0f); +} + +static void drawParticles(float offset) { + float a = offset * angle; + float absoluteAngle = fabs(a); + + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, 10.0f - 6.0f * absoluteAngle / 50.0f); + if (gHeight > gWidth) { + rsMatrixScale(&matrix, 6.6f, 6.0f, 1.0f); + } else { + rsMatrixScale(&matrix, 12.6f, 12.0f, 1.0f); + } + rsMatrixRotate(&matrix, absoluteAngle, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, a, 0.0f, 0.4f, 0.1f); + rsMatrixLoad(&vpConstants->MVP, &vpConstants->Proj); + rsMatrixMultiply(&vpConstants->MVP, &matrix); + rsgAllocationSyncAll(rsGetAllocation(vpConstants)); + + rsgBindProgramVertex(gPVStars); + rsgBindProgramFragment(gPFStars); + rsgBindProgramStore(gPSLights); + rsgBindTexture(gPFStars, 0, gTFlares); + + Particle_t *vtx = Particles; + int count = rsAllocationGetDimX(gParticlesBuffer); + for (int i = 0; i < count; i++) { + vtx->position.x = vtx->position.x + gSpeed[i]; + vtx++; + } + + rsgDrawMesh(gParticlesMesh); +} +/* end of methods for drawing galaxy */ + +// Display sample images in a mesh with different texture +static void displayIcons(int meshMode) { + bindProgramVertexOrtho(); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); + rsgDrawQuadTexCoords( + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, gRenderSurfaceH, 0.0f, 0.0f, 1.0f, + gRenderSurfaceW, gRenderSurfaceH, 0.0f, 1.0f, 1.0f, + gRenderSurfaceW, 0.0f, 0.0f, 1.0f, 0.0f); + + int meshCount = (int)pow(10.0f, (float)(meshMode + 1)); + + float wSize = gRenderSurfaceW/(float)meshCount; + float hSize = gRenderSurfaceH/(float)meshCount; + rs_matrix4x4 matrix; + rsMatrixLoadScale(&matrix, wSize, hSize, 1.0); + + float yPos = 0; + float yPad = hSize / 2; + float xPad = wSize / 2; + for (int y = 0; y < meshCount; y++) { + yPos = y * hSize + yPad; + float xPos = 0; + for (int x = 0; x < meshCount; x++) { + xPos = x * wSize + xPad; + rs_matrix4x4 transMatrix; + rsMatrixLoadTranslate(&transMatrix, xPos, yPos, 0); + rsMatrixMultiply(&transMatrix, &matrix); + rsgProgramVertexLoadModelMatrix(&transMatrix); + int i = (x + y * meshCount) % 100; + rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item); + rsgDrawMesh(gSingleMesh); + } + } +} + +// Draw meshes in a single page with top left corner coordinates (xStart, yStart) +static void drawMeshInPage(float xStart, float yStart, int wResolution, int hResolution) { + // Draw wResolution * hResolution meshes in one page + float wMargin = 100.0f; + float hMargin = 100.0f; + float xPad = 50.0f; + float yPad = 20.0f; + float size = 100.0f; // size of images + + // font info + rs_font font = gFontSans; + rsgBindFont(font); + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + + // Measure text size + int left = 0, right = 0, top = 0, bottom = 0; + rsgMeasureText(gSampleTextList100[0].item, &left, &right, &top, &bottom); + float textHeight = (float)(top - bottom); + float textWidth = (float)(right - left); + + rs_matrix4x4 matrix; + rsMatrixLoadScale(&matrix, size, size, 1.0); + + for (int y = 0; y < hResolution; y++) { + float yPos = yStart + hMargin + y * size + y * yPad; + for (int x = 0; x < wResolution; x++) { + float xPos = xStart + wMargin + x * size + x * xPad; + + rs_matrix4x4 transMatrix; + rsMatrixLoadTranslate(&transMatrix, xPos + size/2, yPos + size/2, 0); + rsMatrixMultiply(&transMatrix, &matrix); // scale the mesh + rsgProgramVertexLoadModelMatrix(&transMatrix); + + int i = (y * wResolution + x) % 100; + rsgBindTexture(gProgFragmentTexture, 0, gTexList100[i].item); + rsgDrawMesh(gSingleMesh); + rsgDrawText(gSampleTextList100[i].item, xPos, yPos + size + yPad/2 + textHeight); + } + } +} + +// Display both images and text as shown in launcher and homepage +// meshMode will decide how many pages we draw +// meshMode = 0: draw 3 pages of meshes +// meshMode = 1: draw 5 pages of meshes +static void displayImageWithText(int wResolution, int hResolution, int meshMode) { + bindProgramVertexOrtho(); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + + drawMeshInPage(0, 0, wResolution, hResolution); + drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + if (meshMode == 1) { + // draw another two pages of meshes + drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); + } +} + +// Display a list of text as the list view +static void displayListView() { + // set text color + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFontSans); + + // get the size of the list + rs_allocation textAlloc; + textAlloc = rsGetAllocation(gListViewText); + int allocSize = rsAllocationGetDimX(textAlloc); + + int listItemHeight = 80; + int yOffset = listItemHeight; + + // set the color for the list divider + rsgBindProgramFragment(gProgFragmentColor); + rsgProgramFragmentConstantColor(gProgFragmentColor, 1.0, 1.0, 1.0, 1); + + // draw the list with divider + for (int i = 0; i < allocSize; i++) { + if (yOffset - listItemHeight > gRenderSurfaceH) { + break; + } + rsgDrawRect(0, yOffset - 1, gRenderSurfaceW, yOffset, 0); + rsgDrawText(gListViewText[i].item, 20, yOffset - 10); + yOffset += listItemHeight; + } +} + +static void drawGalaxy() { + rsgClearColor(0.f, 0.f, 0.f, 1.f); + gParticlesBuffer = rsGetAllocation(Particles); + rsgBindProgramFragment(gPFBackground); + + gWidth = rsgGetWidth(); + gHeight = rsgGetHeight(); + if ((gWidth != gOldWidth) || (gHeight != gOldHeight)) { + initParticles(); + gOldWidth = gWidth; + gOldHeight = gHeight; + } + + float offset = mix(-1.0f, 1.0f, gXOffset); + drawSpace(); + drawParticles(offset); + drawLights(); +} + +// Display images and text with live wallpaper in the background +static void displayLiveWallPaper(int wResolution, int hResolution) { + bindProgramVertexOrtho(); + + drawGalaxy(); + + rsgBindProgramVertex(gProgVertex); + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + + drawMeshInPage(0, 0, wResolution, hResolution); + drawMeshInPage(-1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(1.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(-2.0f*gRenderSurfaceW, 0, wResolution, hResolution); + drawMeshInPage(2.0f*gRenderSurfaceW, 0, wResolution, hResolution); +} + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + TestData *testData = (TestData*)usrData; + gRenderSurfaceW = testData->renderSurfaceW; + gRenderSurfaceH = testData->renderSurfaceH; + gDt = testData->dt; + + gData = (UiTestData*)v_in; + + switch(gData->testId) { + case 0: + displayIcons(gData->user1); + break; + case 1: + displayImageWithText(gData->user1, gData->user2, gData->user3); + break; + case 2: + displayListView(); + break; + case 3: + displayLiveWallPaper(gData->user1, gData->user2); + break; + default: + rsDebug("Wrong test number", 0); + break; + } +} diff --git a/tests/RenderScriptTests/SampleTest/Android.mk b/tests/RenderScriptTests/SampleTest/Android.mk new file mode 100644 index 0000000..7d74c55 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/Android.mk @@ -0,0 +1,26 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := SampleRS + +include $(BUILD_PACKAGE) diff --git a/tests/RenderScriptTests/SampleTest/AndroidManifest.xml b/tests/RenderScriptTests/SampleTest/AndroidManifest.xml new file mode 100644 index 0000000..ec115f7 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?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. +*/ +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rs.sample"> + <uses-sdk android:minSdkVersion="14" /> + <application android:label="Sample Test" + android:hardwareAccelerated="true"> + + <activity android:name="SampleRSActivity" + android:label="Sample Test"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png Binary files differnew file mode 100644 index 0000000..27c4618 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png diff --git a/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png Binary files differnew file mode 100644 index 0000000..98cf963 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png diff --git a/tests/RenderScriptTests/SampleTest/res/layout/rs.xml b/tests/RenderScriptTests/SampleTest/res/layout/rs.xml new file mode 100644 index 0000000..f2a356f --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/res/layout/rs.xml @@ -0,0 +1,84 @@ +<?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. +--> + +<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"> + <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"> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="8pt" + android:text="@string/wraplinear"/> + <TextureView + android:id="@+id/display" + android:layout_width="256sp" + android:layout_height="256sp" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="8pt" + android:text="@string/clamplinear"/> + <TextureView + android:id="@+id/display2" + android:layout_width="256sp" + android:layout_height="256sp" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="8pt" + android:text="@string/wrapnearest"/> + <TextureView + android:id="@+id/display3" + android:layout_width="256sp" + android:layout_height="256sp" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="8pt" + android:text="@string/clampnearest"/> + <TextureView + android:id="@+id/display4" + android:layout_width="256sp" + android:layout_height="256sp" /> + <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/benchmark"/> + </LinearLayout> + </LinearLayout> + </ScrollView> +</LinearLayout> + diff --git a/tests/RenderScriptTests/SampleTest/res/values/strings.xml b/tests/RenderScriptTests/SampleTest/res/values/strings.xml new file mode 100644 index 0000000..a0a2499 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/res/values/strings.xml @@ -0,0 +1,28 @@ +<?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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- General --> + <skip /> + <string name="benchmark">Benchmark</string> + <string name="wraplinear">Wrap Linear</string> + <string name="clamplinear">Clamp Linear</string> + <string name="wrapnearest">Wrap Nearest</string> + <string name="clampnearest">Clamp Nearest</string> +</resources> diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java new file mode 100644 index 0000000..77cbf84 --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java @@ -0,0 +1,169 @@ +/* + * 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.sample; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.SurfaceTexture; +import android.os.Bundle; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Matrix3f; +import android.renderscript.RenderScript; +import android.renderscript.Sampler; +import android.renderscript.Type; +import android.renderscript.Type.Builder; +import android.util.Log; +import android.view.TextureView; +import android.view.TextureView.SurfaceTextureListener; +import android.view.View; +import android.widget.ImageView; +import android.widget.SeekBar; +import android.widget.TextView; + +public class SampleRSActivity extends Activity { + class TextureViewUpdater implements TextureView.SurfaceTextureListener { + private Allocation mOutPixelsAllocation; + private Sampler mSampler; + + TextureViewUpdater(Allocation outAlloc, Sampler sampler) { + mOutPixelsAllocation = outAlloc; + mSampler = sampler; + } + + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + } + + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + mOutPixelsAllocation.setSurfaceTexture(surface); + } + + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + mOutPixelsAllocation.setSurfaceTexture(surface); + filterAlloc(mOutPixelsAllocation, mSampler); + } + + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + mOutPixelsAllocation.setSurfaceTexture(null); + return true; + } + } + + private final String TAG = "Img"; + private Bitmap mBitmapTwoByTwo; + private Bitmap mBitmapCity; + + private TextView mBenchmarkResult; + + private RenderScript mRS; + private Allocation mTwoByTwoAlloc; + private Allocation mCityAlloc; + private ScriptC_sample mScript; + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.rs); + + mBitmapTwoByTwo = loadBitmap(R.drawable.twobytwo); + mBitmapCity = loadBitmap(R.drawable.city); + + mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); + mBenchmarkResult.setText("Result: not run"); + + mRS = RenderScript.create(this); + mTwoByTwoAlloc = Allocation.createFromBitmap(mRS, mBitmapTwoByTwo, + Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_SCRIPT); + + mCityAlloc = Allocation.createFromBitmap(mRS, mBitmapCity, + Allocation.MipmapControl.MIPMAP_NONE, + Allocation.USAGE_SCRIPT); + + Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS)); + + int usage = Allocation.USAGE_SCRIPT | Allocation.USAGE_IO_OUTPUT; + + int outX = 256; + int outY = 256; + + // Wrap Linear + Allocation outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage); + TextureViewUpdater updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_LINEAR(mRS)); + TextureView displayView = (TextureView) findViewById(R.id.display); + displayView.setSurfaceTextureListener(updater); + + // Clamp Linear + outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage); + updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_LINEAR(mRS)); + displayView = (TextureView) findViewById(R.id.display2); + displayView.setSurfaceTextureListener(updater); + + // Wrap Nearest + outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage); + updater = new TextureViewUpdater(outAlloc, Sampler.WRAP_NEAREST(mRS)); + displayView = (TextureView) findViewById(R.id.display3); + displayView.setSurfaceTextureListener(updater); + + // Clamp Nearest + outAlloc = Allocation.createTyped(mRS, b.setX(outX).setY(outY).create(), usage); + updater = new TextureViewUpdater(outAlloc, Sampler.CLAMP_NEAREST(mRS)); + displayView = (TextureView) findViewById(R.id.display4); + displayView.setSurfaceTextureListener(updater); + + mScript = new ScriptC_sample(mRS, getResources(), R.raw.sample); + } + + private Bitmap loadBitmap(int resource) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inPreferredConfig = Bitmap.Config.ARGB_8888; + Bitmap b = BitmapFactory.decodeResource(getResources(), resource, options); + Bitmap b2 = Bitmap.createBitmap(b.getWidth(), b.getHeight(), b.getConfig()); + Canvas c = new Canvas(b2); + c.drawBitmap(b, 0, 0, null); + b.recycle(); + return b2; + } + + private synchronized void filterAlloc(Allocation alloc, Sampler sampler) { + long t = java.lang.System.currentTimeMillis(); + mScript.invoke_setSampleData(alloc, mTwoByTwoAlloc, sampler); + mScript.forEach_root(alloc); + alloc.ioSendOutput(); + mRS.finish(); + t = java.lang.System.currentTimeMillis() - t; + Log.i(TAG, "Filter time is: " + t + " ms"); + } + + public void benchmark(View v) { + /*filterAlloc(); + long t = java.lang.System.currentTimeMillis(); + filterAlloc(); + t = java.lang.System.currentTimeMillis() - t; + mDisplayView.invalidate(); + mBenchmarkResult.setText("Result: " + t + " ms");*/ + } +} diff --git a/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs new file mode 100644 index 0000000..e2bf43d --- /dev/null +++ b/tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#pragma version(1) +#pragma rs java_package_name(com.android.rs.sample) +#include "rs_graphics.rsh" + +static rs_allocation sourceAlloc; +static rs_allocation destAlloc; +static rs_sampler allocSampler; + +void setSampleData(rs_allocation dest, rs_allocation source, rs_sampler sampler) { + destAlloc = dest; + sourceAlloc = source; + allocSampler = sampler; +} + +void root(uchar4 *out, uint32_t x, uint32_t y) { + + float destX = (float)rsAllocationGetDimX(destAlloc) - 1.0f; + float destY = (float)rsAllocationGetDimY(destAlloc) - 1.0f; + + float2 uv; + uv.x = (float)x / destX; + uv.y = (float)y / destY; + + out->xyz = convert_uchar3(rsSample(sourceAlloc, allocSampler, uv*2.0f).xyz); + out->w = 0xff; +} + diff --git a/tests/RenderScriptTests/SceneGraph/Android.mk b/tests/RenderScriptTests/SceneGraph/Android.mk new file mode 100644 index 0000000..ba4b3c5 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/Android.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := SceneGraphTest + +include $(BUILD_PACKAGE) diff --git a/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml b/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml new file mode 100644 index 0000000..67af0fa --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testapp"> + <uses-permission + android:name="android.permission.INTERNET" /> + <application android:label="SceneGraphTest"> + <activity android:name="TestApp" + android:label="SceneGraphTest"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name="SimpleApp" + android:label="SimpleSceneGraph"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name="FileSelector" + android:label="FileSelector" + android:hardwareAccelerated="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/SceneGraph/assets/blue.jpg b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg Binary files differnew file mode 100644 index 0000000..494e77a --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg Binary files differnew file mode 100644 index 0000000..2fcecb0 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/green.jpg b/tests/RenderScriptTests/SceneGraph/assets/green.jpg Binary files differnew file mode 100644 index 0000000..a86a754 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/green.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/grey.jpg b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg Binary files differnew file mode 100644 index 0000000..5870b1a --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/orange.jpg b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg Binary files differnew file mode 100644 index 0000000..7dbe942 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d Binary files differnew file mode 100644 index 0000000..07318ae --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae new file mode 100644 index 0000000..7eef443 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae @@ -0,0 +1,1102 @@ +<?xml version="1.0" ?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1"> + <asset> + <contributor> + <author>alexst</author> + <authoring_tool>OpenCOLLADA2010</authoring_tool> + <comments>ColladaMaya export options: bakeTransforms=0;relativePaths=0;copyTextures=0;exportTriangles=1;exportCgfxFileReferences=0; isSampling=0;curveConstrainSampling=0;removeStaticCurves=1;exportPolygonMeshes=1;exportLights=1; exportCameras=1;exportJointsAndSkin=1;exportAnimations=0;exportInvisibleNodes=0;exportDefaultCameras=0; exportTexCoords=1;exportNormals=1;exportNormalsPerVertex=1;exportVertexColors=0;exportVertexColorsPerVertex=0; exportTexTangents=0;exportTangents=0;exportReferencedMaterials=1;exportMaterialsOnly=0; exportXRefs=1;dereferenceXRefs=1;exportCameraAsLookat=0;cameraXFov=0;cameraYFov=1;doublePrecision=0</comments> + <source_data>file:///Volumes/Android/art/orientation_test.mb</source_data> + </contributor> + <created>2011-09-30T15:31:38</created> + <modified>2011-09-30T15:31:38</modified> + <unit meter="0.01" name="centimeter" /> + <up_axis>Y_UP</up_axis> + </asset> + <library_cameras> + <camera id="cameraShape1" name="cameraShape1"> + <optics> + <technique_common> + <perspective> + <yfov>37.8493</yfov> + <aspect_ratio>1.5</aspect_ratio> + <znear>1</znear> + <zfar>400</zfar> + </perspective> + </technique_common> + </optics> + <extra> + <technique profile="OpenCOLLADAMaya"> + <film_fit>0</film_fit> + <film_fit_offset>0</film_fit_offset> + <film_offsetX>0</film_offsetX> + <film_offsetY>0</film_offsetY> + <horizontal_aperture>3.599993</horizontal_aperture> + <lens_squeeze>1</lens_squeeze> + <originalMayaNodeId>cameraShape1</originalMayaNodeId> + <vertical_aperture>2.399995</vertical_aperture> + </technique> + </extra> + </camera> + <camera id="CameraDistShape" name="CameraDistShape"> + <optics> + <technique_common> + <perspective> + <yfov>37.8493</yfov> + <aspect_ratio>1.5</aspect_ratio> + <znear>1</znear> + <zfar>1000</zfar> + </perspective> + </technique_common> + </optics> + <extra> + <technique profile="OpenCOLLADAMaya"> + <film_fit>0</film_fit> + <film_fit_offset>0</film_fit_offset> + <film_offsetX>0</film_offsetX> + <film_offsetY>0</film_offsetY> + <horizontal_aperture>3.599993</horizontal_aperture> + <lens_squeeze>1</lens_squeeze> + <originalMayaNodeId>CameraDistShape</originalMayaNodeId> + <vertical_aperture>2.399995</vertical_aperture> + </technique> + </extra> + </camera> + </library_cameras> + <library_materials> + <material id="Paint1" name="Paint1"> + <instance_effect url="#Paint1-fx" /> + </material> + <material id="lambert2" name="lambert2"> + <instance_effect url="#lambert2-fx" /> + </material> + <material id="Plastic" name="Plastic"> + <instance_effect url="#Plastic-fx" /> + </material> + <material id="Metal" name="Metal"> + <instance_effect url="#Metal-fx" /> + </material> + <material id="PlasticCenter" name="PlasticCenter"> + <instance_effect url="#PlasticCenter-fx" /> + </material> + <material id="PlasticRed" name="PlasticRed"> + <instance_effect url="#PlasticRed-fx" /> + </material> + <material id="lambert10" name="lambert10"> + <instance_effect url="#lambert10-fx" /> + </material> + <material id="lambert11" name="lambert11"> + <instance_effect url="#lambert11-fx" /> + </material> + </library_materials> + <library_effects> + <effect id="Metal-fx"> + <profile_COMMON> + <newparam sid="file23-surface"> + <surface type="2D"> + <init_from>file23</init_from> + </surface> + </newparam> + <newparam sid="file23-sampler"> + <sampler2D> + <source>file23-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file23-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="Paint1-fx"> + <profile_COMMON> + <newparam sid="file25-surface"> + <surface type="2D"> + <init_from>file25</init_from> + </surface> + </newparam> + <newparam sid="file25-sampler"> + <sampler2D> + <source>file25-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file25-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="Plastic-fx"> + <profile_COMMON> + <newparam sid="file24-surface"> + <surface type="2D"> + <init_from>file24</init_from> + </surface> + </newparam> + <newparam sid="file24-sampler"> + <sampler2D> + <source>file24-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file24-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="PlasticCenter-fx"> + <profile_COMMON> + <newparam sid="file24-surface"> + <surface type="2D"> + <init_from>file24</init_from> + </surface> + </newparam> + <newparam sid="file24-sampler"> + <sampler2D> + <source>file24-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file24-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="PlasticRed-fx"> + <profile_COMMON> + <newparam sid="file23-surface"> + <surface type="2D"> + <init_from>file23</init_from> + </surface> + </newparam> + <newparam sid="file23-sampler"> + <sampler2D> + <source>file23-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file23-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="lambert10-fx"> + <profile_COMMON> + <newparam sid="file28-surface"> + <surface type="2D"> + <init_from>file28</init_from> + </surface> + </newparam> + <newparam sid="file28-sampler"> + <sampler2D> + <source>file28-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file28-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="lambert11-fx"> + <profile_COMMON> + <newparam sid="file29-surface"> + <surface type="2D"> + <init_from>file29</init_from> + </surface> + </newparam> + <newparam sid="file29-sampler"> + <sampler2D> + <source>file29-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file29-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + <effect id="lambert2-fx"> + <profile_COMMON> + <newparam sid="file22-surface"> + <surface type="2D"> + <init_from>file22</init_from> + </surface> + </newparam> + <newparam sid="file22-sampler"> + <sampler2D> + <source>file22-surface</source> + </sampler2D> + </newparam> + <technique sid="common"> + <lambert> + <emission> + <color>0 0 0 1</color> + </emission> + <ambient> + <color>0 0 0 1</color> + </ambient> + <diffuse> + <texture texture="file22-sampler" texcoord="TEX0"> + <extra> + <technique profile="OpenCOLLADAMaya"> + <blend_mode>NONE</blend_mode> + <coverageU>1</coverageU> + <coverageV>1</coverageV> + <fast>0</fast> + <mirrorU>0</mirrorU> + <mirrorV>0</mirrorV> + <noiseU>0</noiseU> + <noiseV>0</noiseV> + <offsetU>0</offsetU> + <offsetV>0</offsetV> + <repeatU>1</repeatU> + <repeatV>1</repeatV> + <rotateFrame>0</rotateFrame> + <rotateUV>0</rotateUV> + <stagger>0</stagger> + <translateFrameU>0</translateFrameU> + <translateFrameV>0</translateFrameV> + <wrapU>1</wrapU> + <wrapV>1</wrapV> + </technique> + </extra> + </texture> + </diffuse> + <transparent opaque="RGB_ZERO"> + <color>0 0 0 1</color> + </transparent> + <transparency> + <float>1</float> + </transparency> + </lambert> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_images> + <image id="file29" name="file29" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/blue.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file29</originalMayaNodeId> + </technique> + </extra> + </image> + <image id="file25" name="file25" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/carbonfiber.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file25</originalMayaNodeId> + </technique> + </extra> + </image> + <image id="file28" name="file28" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/green.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file28</originalMayaNodeId> + </technique> + </extra> + </image> + <image id="file22" name="file22" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/grey.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file22</originalMayaNodeId> + </technique> + </extra> + </image> + <image id="file24" name="file24" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/orange.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file24</originalMayaNodeId> + </technique> + </extra> + </image> + <image id="file23" name="file23" height="0" width="0"> + <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/red.jpg</init_from> + <extra> + <technique profile="OpenCOLLADAMaya"> + <dgnode_type>kFile</dgnode_type> + <image_sequence>0</image_sequence> + <originalMayaNodeId>file23</originalMayaNodeId> + </technique> + </extra> + </image> + </library_images> + <library_visual_scenes> + <visual_scene id="VisualSceneNode" name="orientation_test"> + <node id="camera1" name="camera1"> + <translate sid="translate">24.5791 14.1321 31.4654</translate> + <rotate sid="rotateZ">0 0 1 0</rotate> + <rotate sid="rotateY">0 1 0 42</rotate> + <rotate sid="rotateX">1 0 0 -16.2</rotate> + <scale sid="scale">1 1 1</scale> + <instance_camera url="#cameraShape1" /> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>camera1</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="CameraAim" name="CameraAim"> + <translate sid="translate">0.0209301 3.68542 2.06912</translate> + <rotate sid="rotateY">0 1 0 43.2561</rotate> + <rotate sid="rotateX">1 0 0 -20</rotate> + <scale sid="scale">1 1 1</scale> + <node id="CameraDist" name="CameraDist"> + <translate sid="translate">0 0 45</translate> + <scale sid="scale">1 1 1</scale> + <instance_camera url="#CameraDistShape" /> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>CameraDist</originalMayaNodeId> + </technique> + </extra> + </node> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>CameraAim</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere4" name="pSphere4"> + <translate sid="translate">-9.69237 0 7.70498</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape4"> + <bind_material> + <technique_common> + <instance_material symbol="lambert7SG" target="#Paint1"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere4</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere1" name="pSphere1"> + <translate sid="translate">13.0966 0 5.76254</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape1"> + <bind_material> + <technique_common> + <instance_material symbol="lambert7SG" target="#Paint1"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere1</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere2" name="pSphere2"> + <translate sid="translate">21.7661 0 -13.6375</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape2"> + <bind_material> + <technique_common> + <instance_material symbol="lambert7SG" target="#Paint1"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere2</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere3" name="pSphere3"> + <translate sid="translate">-13.862 0 -13.6154</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape3"> + <bind_material> + <technique_common> + <instance_material symbol="lambert7SG" target="#Paint1"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere3</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere5" name="pSphere5"> + <translate sid="translate">31.0862 0 18.5992</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape5"> + <bind_material> + <technique_common> + <instance_material symbol="lambert7SG" target="#Paint1"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere5</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pCube1" name="pCube1"> + <translate sid="translate">0 0 0</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pCubeShape1"> + <bind_material> + <technique_common> + <instance_material symbol="lambert4SG" target="#lambert2"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pCube1</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="group1" name="group1"> + <translate sid="translate">0 0 0</translate> + <rotate sid="rotateZ">0 0 1 -162.693</rotate> + <rotate sid="rotateY">0 1 0 21.3345</rotate> + <rotate sid="rotateX">1 0 0 -100.567</rotate> + <scale sid="scale">1 1 1</scale> + <node id="pSphere6" name="pSphere6"> + <translate sid="translate">-13.862 0 -13.6154</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape6"> + <bind_material> + <technique_common> + <instance_material symbol="lambert6SG" target="#Plastic"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere6</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere7" name="pSphere7"> + <translate sid="translate">-9.69237 0 7.70498</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape7"> + <bind_material> + <technique_common> + <instance_material symbol="lambert6SG" target="#Plastic"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere7</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere8" name="pSphere8"> + <translate sid="translate">21.7661 0 -13.6375</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape8"> + <bind_material> + <technique_common> + <instance_material symbol="lambert6SG" target="#Plastic"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere8</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere9" name="pSphere9"> + <translate sid="translate">13.0966 0 5.76254</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape9"> + <bind_material> + <technique_common> + <instance_material symbol="lambert6SG" target="#Plastic"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere9</originalMayaNodeId> + </technique> + </extra> + </node> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>group1</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="group2" name="group2"> + <translate sid="translate">0 0 0</translate> + <rotate sid="rotateZ">0 0 1 45.4017</rotate> + <rotate sid="rotateY">0 1 0 79.393</rotate> + <rotate sid="rotateX">1 0 0 5.10889</rotate> + <scale sid="scale">1 1 1</scale> + <node id="pSphere10" name="pSphere10"> + <translate sid="translate">31.0862 0 18.5992</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape10"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere10</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere11" name="pSphere11"> + <translate sid="translate">13.0966 0 5.76254</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape11"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere11</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere12" name="pSphere12"> + <translate sid="translate">7.4784 16.3496 7.36882</translate> + <rotate sid="rotateZ">0 0 1 17.3073</rotate> + <rotate sid="rotateY">0 1 0 158.666</rotate> + <rotate sid="rotateX">1 0 0 79.4335</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape12"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere12</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere13" name="pSphere13"> + <translate sid="translate">-9.69237 0 7.70498</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape13"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere13</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere14" name="pSphere14"> + <translate sid="translate">11.3635 -4.3926 2.21012</translate> + <rotate sid="rotateZ">0 0 1 17.3073</rotate> + <rotate sid="rotateY">0 1 0 158.666</rotate> + <rotate sid="rotateX">1 0 0 79.4335</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape14"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere14</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere15" name="pSphere15"> + <translate sid="translate">21.7661 0 -13.6375</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape15"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere15</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere16" name="pSphere16"> + <translate sid="translate">-9.5945 -8.92317 -5.74901</translate> + <rotate sid="rotateZ">0 0 1 17.3073</rotate> + <rotate sid="rotateY">0 1 0 158.666</rotate> + <rotate sid="rotateX">1 0 0 79.4335</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape16"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere16</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere17" name="pSphere17"> + <translate sid="translate">-13.862 0 -13.6154</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape17"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere17</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pSphere18" name="pSphere18"> + <translate sid="translate">-24.2135 6.497 -5.58935</translate> + <rotate sid="rotateZ">0 0 1 17.3073</rotate> + <rotate sid="rotateY">0 1 0 158.666</rotate> + <rotate sid="rotateX">1 0 0 79.4335</rotate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pSphereShape18"> + <bind_material> + <technique_common> + <instance_material symbol="lambert5SG" target="#Metal"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pSphere18</originalMayaNodeId> + </technique> + </extra> + </node> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>group2</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pCube2" name="pCube2"> + <translate sid="translate">0 0 0</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pCubeShape2"> + <bind_material> + <technique_common> + <instance_material symbol="lambert8SG" target="#PlasticCenter"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pCube2</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pCube3" name="pCube3"> + <translate sid="translate">15 0 0</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pCubeShape3"> + <bind_material> + <technique_common> + <instance_material symbol="lambert9SG" target="#PlasticRed"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pCube3</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pCube4" name="pCube4"> + <translate sid="translate">0 15 0</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pCubeShape4"> + <bind_material> + <technique_common> + <instance_material symbol="lambert10SG" target="#lambert10"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pCube4</originalMayaNodeId> + </technique> + </extra> + </node> + <node id="pCube5" name="pCube5"> + <translate sid="translate">0 0 15</translate> + <scale sid="scale">1 1 1</scale> + <instance_geometry url="#pCubeShape5"> + <bind_material> + <technique_common> + <instance_material symbol="lambert11SG" target="#lambert11"> + <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" /> + </instance_material> + </technique_common> + </bind_material> + </instance_geometry> + <extra> + <technique profile="OpenCOLLADAMaya"> + <originalMayaNodeId>pCube5</originalMayaNodeId> + </technique> + </extra> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#VisualSceneNode" /> + </scene> +</COLLADA> diff --git a/tests/RenderScriptTests/SceneGraph/assets/paint.jpg b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg Binary files differnew file mode 100644 index 0000000..0791045 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/red.jpg b/tests/RenderScriptTests/SceneGraph/assets/red.jpg Binary files differnew file mode 100644 index 0000000..320a2a6 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/red.jpg diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png Binary files differnew file mode 100644 index 0000000..ff34a7f --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png Binary files differnew file mode 100644 index 0000000..f7353fd --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png diff --git a/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml b/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml new file mode 100644 index 0000000..9ea30107 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +--> + +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@+id/load_model" + android:title="@string/load_model" /> + <item android:id="@+id/use_blur" + android:title="@string/use_blur" /> +</menu> diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl new file mode 100644 index 0000000..c34adc9 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl @@ -0,0 +1,15 @@ +varying vec2 varTex0; + +void main() { + vec2 blurCoord = varTex0; + blurCoord.x = varTex0.x + UNI_blurOffset0; + vec3 col = texture2D(UNI_color, blurCoord).rgb; + blurCoord.x = varTex0.x + UNI_blurOffset1; + col += texture2D(UNI_color, blurCoord).rgb; + blurCoord.x = varTex0.x + UNI_blurOffset2; + col += texture2D(UNI_color, blurCoord).rgb; + blurCoord.x = varTex0.x + UNI_blurOffset3; + col += texture2D(UNI_color, blurCoord).rgb; + + gl_FragColor = vec4(col * 0.25, 0.0); +} diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl new file mode 100644 index 0000000..ade05a2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl @@ -0,0 +1,17 @@ +varying vec2 varTex0; + +void main() { + vec2 blurCoord = varTex0; + blurCoord.y = varTex0.y + UNI_blurOffset0; + vec3 col = texture2D(UNI_color, blurCoord).rgb; + blurCoord.y = varTex0.y + UNI_blurOffset1; + col += texture2D(UNI_color, blurCoord).rgb; + blurCoord.y = varTex0.y + UNI_blurOffset2; + col += texture2D(UNI_color, blurCoord).rgb; + blurCoord.y = varTex0.y + UNI_blurOffset3; + col += texture2D(UNI_color, blurCoord).rgb; + + col = col * 0.25; + + gl_FragColor = vec4(col, 0.0); +} diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl new file mode 100644 index 0000000..bc824b6 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl @@ -0,0 +1,7 @@ +varying vec2 varTex0; + +void main() { + gl_Position = ATTRIB_position; + varTex0 = ATTRIB_texture0; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl new file mode 100644 index 0000000..2eb1028 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl @@ -0,0 +1,19 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = (varWorldNormal); + + vec3 light0Vec = V; + vec3 light0R = reflect(light0Vec, worldNorm); + float light0_Diffuse = dot(worldNorm, light0Vec); + + vec2 t0 = varTex0.xy; + lowp vec4 col = texture2D(UNI_diffuse, t0).rgba; + col.xyz = col.xyz * light0_Diffuse * 1.2; + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/diffuse_lights.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse_lights.glsl new file mode 100644 index 0000000..ef93e1c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse_lights.glsl @@ -0,0 +1,22 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = normalize(UNI_lightPos_0.xyz - varWorldPos.xyz); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0); + + vec3 light1Vec = normalize(UNI_lightPos_1.xyz - varWorldPos.xyz); + float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0); + + vec2 t0 = varTex0.xy; + lowp vec4 col = UNI_diffuse; + col.xyz = col.xyz * (light0_Diffuse * UNI_lightColor_0.xyz + + light1_Diffuse * UNI_lightColor_1.xyz); + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl new file mode 100644 index 0000000..b90a7b2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl @@ -0,0 +1,23 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = V; + vec3 light0R = reflect(light0Vec, worldNorm); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0); + float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0); + float light0_Specular = pow(light0Spec, 15.0) * 0.5; + + vec2 t0 = varTex0.xy; + lowp vec4 col = texture2D(UNI_diffuse, t0).rgba; + col.xyz = col.xyz * (textureCube(UNI_reflection, worldNorm).rgb * 0.5 + vec3(light0_Diffuse)); + col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0); + + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl new file mode 100644 index 0000000..f3b89ed --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl @@ -0,0 +1,26 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = V; + vec3 light0R = reflect(light0Vec, worldNorm); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.01, 0.99); + float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0); + float light0_Specular = pow(light0Spec, 150.0) * 0.5; + + vec2 t0 = varTex0.xy; + lowp vec4 col = texture2D(UNI_diffuse, t0).rgba; + col.xyz = col.xyz * light0_Diffuse * 1.1; + col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0); + + float fresnel = mix(pow(1.0 - light0_Diffuse, 15.0), 1.0, 0.1); + col.xyz = mix(col.xyz, textureCube(UNI_reflection, -light0R).rgb * 2.4, fresnel); + col.w = 0.8; + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl new file mode 100644 index 0000000..56f7151 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl @@ -0,0 +1,22 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = V; + vec3 light0R = reflect(light0Vec, worldNorm); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0); + float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0); + float light0_Specular = pow(light0Spec, 10.0) * 0.5; + + vec2 t0 = varTex0.xy; + lowp vec4 col = texture2D(UNI_diffuse, t0).rgba; + col.xyz = col.xyz * light0_Diffuse * 1.2; + col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0); + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl new file mode 100644 index 0000000..b253622 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl @@ -0,0 +1,29 @@ +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +void main() { + + vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz); + vec3 worldNorm = normalize(varWorldNormal); + + vec3 light0Vec = normalize(UNI_lightPos_0.xyz - varWorldPos.xyz); + vec3 light0R = reflect(light0Vec, worldNorm); + float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0); + float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0); + float light0_Specular = pow(light0Spec, 10.0) * 0.7; + + vec3 light1Vec = normalize(UNI_lightPos_1.xyz - varWorldPos.xyz); + vec3 light1R = reflect(light1Vec, worldNorm); + float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0); + float light1Spec = clamp(dot(-light1R, V), 0.001, 1.0); + float light1_Specular = pow(light1Spec, 10.0) * 0.7; + + vec2 t0 = varTex0.xy; + lowp vec4 col = UNI_diffuse; + col.xyz = col.xyz * (light0_Diffuse * UNI_lightColor_0.xyz + + light1_Diffuse * UNI_lightColor_1.xyz); + col.xyz += (light0_Specular + light1_Specular); + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d Binary files differnew file mode 100644 index 0000000..f48895c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl new file mode 100644 index 0000000..1a927ca --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl @@ -0,0 +1,13 @@ +varying vec2 varTex0; + +void main() { + vec3 col = texture2D(UNI_color, varTex0).rgb; + + vec3 desat = vec3(0.299, 0.587, 0.114); + float lum = dot(desat, col); + float stepVal = step(lum, 0.8); + col = mix(col, vec3(0.0), stepVal)*0.5; + + gl_FragColor = vec4(col, 0.0); +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl new file mode 100644 index 0000000..7910a54 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl @@ -0,0 +1,22 @@ +/* + rs_matrix4x4 model; + rs_matrix4x4 viewProj; +*/ + +varying vec3 varWorldPos; +varying vec3 varWorldNormal; +varying vec2 varTex0; + +// This is where actual shader code begins +void main() { + vec4 objPos = ATTRIB_position; + vec4 worldPos = UNI_model * objPos; + gl_Position = UNI_viewProj * worldPos; + + mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz); + vec3 worldNorm = model3 * ATTRIB_normal; + + varWorldPos = worldPos.xyz; + varWorldNormal = worldNorm; + varTex0 = ATTRIB_texture0; +} diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl new file mode 100644 index 0000000..662ecd8 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl @@ -0,0 +1,7 @@ +varying vec2 varTex0; + +void main() { + lowp vec4 col = texture2D(UNI_color, varTex0).rgba; + gl_FragColor = col; +} + diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d Binary files differnew file mode 100644 index 0000000..56eff04 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d diff --git a/tests/RenderScriptTests/SceneGraph/res/values/strings.xml b/tests/RenderScriptTests/SceneGraph/res/values/strings.xml new file mode 100644 index 0000000..c916d79 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/values/strings.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <skip /> + <string name="load_model">Load Model</string> + <string name="use_blur">Use Blur</string> +</resources> diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java new file mode 100644 index 0000000..42f2be5 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import com.android.scenegraph.SceneManager; + +import android.renderscript.*; +import android.renderscript.Matrix4f; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public class Camera extends SceneGraphBase { + + Transform mTransform; + + ScriptField_Camera_s.Item mData; + ScriptField_Camera_s mField; + + public Camera() { + mData = new ScriptField_Camera_s.Item(); + mData.near = 0.1f; + mData.far = 1000.0f; + mData.horizontalFOV = 60.0f; + mData.aspect = 0; + } + + public void setTransform(Transform t) { + mTransform = t; + if (mField != null) { + mField.set_transformMatrix(0, mTransform.getRSData().getAllocation(), true); + mField.set_isDirty(0, 1, true); + } + } + public void setFOV(float fov) { + mData.horizontalFOV = fov; + if (mField != null) { + mField.set_horizontalFOV(0, fov, true); + mField.set_isDirty(0, 1, true); + } + } + + public void setNear(float n) { + mData.near = n; + if (mField != null) { + mField.set_near(0, n, true); + mField.set_isDirty(0, 1, true); + } + } + + public void setFar(float f) { + mData.far = f; + if (mField != null) { + mField.set_far(0, f, true); + mField.set_isDirty(0, 1, true); + } + } + + public void setName(String n) { + super.setName(n); + if (mField != null) { + RenderScriptGL rs = SceneManager.getRS(); + mData.name = getNameAlloc(rs); + mField.set_name(0, mData.name, true); + mField.set_isDirty(0, 1, true); + } + } + + ScriptField_Camera_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + + if (mTransform == null) { + throw new RuntimeException("Cameras without transforms are invalid"); + } + + mField = new ScriptField_Camera_s(rs, 1); + + mData.transformMatrix = mTransform.getRSData().getAllocation(); + mData.transformTimestamp = 1; + mData.timestamp = 1; + mData.isDirty = 1; + mData.name = getNameAlloc(rs); + mField.set(mData, 0, true); + + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java new file mode 100644 index 0000000..b4b6fb9 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java @@ -0,0 +1,563 @@ +/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.scenegraph;
+import com.android.scenegraph.CompoundTransform.TranslateComponent;
+import com.android.scenegraph.CompoundTransform.RotateComponent;
+import com.android.scenegraph.CompoundTransform.ScaleComponent;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.HashMap;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class ColladaParser {
+ static final String TAG = "ColladaParser";
+ Document mDom;
+
+ HashMap<String, LightBase> mLights;
+ HashMap<String, Camera> mCameras;
+ HashMap<String, ArrayList<ShaderParam> > mEffectsParams;
+ HashMap<String, Texture2D> mImages;
+ HashMap<String, Texture2D> mSamplerImageMap;
+ HashMap<String, String> mMeshIdNameMap;
+ Scene mScene;
+
+ String mRootDir;
+
+ String toString(Float3 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z;
+ return valueStr;
+ }
+
+ String toString(Float4 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z + " " + v.w;
+ return valueStr;
+ }
+
+ public ColladaParser(){
+ mLights = new HashMap<String, LightBase>();
+ mCameras = new HashMap<String, Camera>();
+ mEffectsParams = new HashMap<String, ArrayList<ShaderParam> >();
+ mImages = new HashMap<String, Texture2D>();
+ mMeshIdNameMap = new HashMap<String, String>();
+ }
+
+ public void init(InputStream is, String rootDir) {
+ mLights.clear();
+ mCameras.clear();
+ mEffectsParams.clear();
+
+ mRootDir = rootDir;
+
+ long start = System.currentTimeMillis();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ mDom = db.parse(is);
+ } catch(ParserConfigurationException e) {
+ e.printStackTrace();
+ } catch(SAXException e) {
+ e.printStackTrace();
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", " Parse time: " + (end - start));
+ exportSceneData();
+ }
+
+ Scene getScene() {
+ return mScene;
+ }
+
+ private void exportSceneData(){
+ mScene = new Scene();
+
+ Element docEle = mDom.getDocumentElement();
+ NodeList nl = docEle.getElementsByTagName("light");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element l = (Element)nl.item(i);
+ convertLight(l);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("camera");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element c = (Element)nl.item(i);
+ convertCamera(c);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("image");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element img = (Element)nl.item(i);
+ convertImage(img);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("effect");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element e = (Element)nl.item(i);
+ convertEffects(e);
+ }
+ }
+
+ // Material is just a link to the effect
+ nl = docEle.getElementsByTagName("material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertMaterials(m);
+ }
+ }
+
+ // Look through the geometry list and build up a correlation between id's and names
+ nl = docEle.getElementsByTagName("geometry");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertGeometries(m);
+ }
+ }
+
+
+ nl = docEle.getElementsByTagName("visual_scene");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element s = (Element)nl.item(i);
+ getScene(s);
+ }
+ }
+ }
+
+ private void getRenderable(Element shape, Transform t) {
+ String geoURL = shape.getAttribute("url").substring(1);
+ String geoName = mMeshIdNameMap.get(geoURL);
+ if (geoName != null) {
+ geoURL = geoName;
+ }
+ //RenderableGroup group = new RenderableGroup();
+ //group.setName(geoURL.substring(1));
+ //mScene.appendRenderable(group);
+ NodeList nl = shape.getElementsByTagName("instance_material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element materialRef = (Element)nl.item(i);
+ String meshIndexName = materialRef.getAttribute("symbol");
+ String materialName = materialRef.getAttribute("target");
+
+ Renderable d = new Renderable();
+ d.setMesh(geoURL, meshIndexName);
+ d.setMaterialName(materialName.substring(1));
+ d.setName(geoURL);
+
+ //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
+
+ d.setTransform(t);
+ //Log.v(TAG, "Set source param " + t.getName());
+
+ // Now find all the parameters that exist on the material
+ ArrayList<ShaderParam> materialParams;
+ materialParams = mEffectsParams.get(materialName.substring(1));
+ for (int pI = 0; pI < materialParams.size(); pI ++) {
+ d.appendSourceParams(materialParams.get(pI));
+ //Log.v(TAG, "Set source param i: " + pI + " name " + materialParams.get(pI).getParamName());
+ }
+ mScene.appendRenderable(d);
+ //group.appendChildren(d);
+ }
+ }
+ }
+
+ private void updateLight(Element shape, Transform t) {
+ String lightURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ LightBase light = mLights.get(lightURL.substring(1));
+ if (light != null) {
+ light.setTransform(t);
+ //Log.v(TAG, "Set Light " + light.getName() + " " + t.getName());
+ }
+ }
+
+ private void updateCamera(Element shape, Transform t) {
+ String camURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ Camera cam = mCameras.get(camURL.substring(1));
+ if (cam != null) {
+ cam.setTransform(t);
+ //Log.v(TAG, "Set Camera " + cam.getName() + " " + t.getName());
+ }
+ }
+
+ private void getNode(Element node, Transform parent, String indent) {
+ String name = node.getAttribute("name");
+ String id = node.getAttribute("id");
+ CompoundTransform current = new CompoundTransform();
+ current.setName(name);
+ if (parent != null) {
+ parent.appendChild(current);
+ } else {
+ mScene.appendTransform(current);
+ }
+
+ mScene.addToTransformMap(current);
+
+ //Log.v(TAG, indent + "|");
+ //Log.v(TAG, indent + "[" + name + "]");
+
+ Node childNode = node.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element field = (Element)childNode;
+ String fieldName = field.getTagName();
+ String description = field.getAttribute("sid");
+ if (fieldName.equals("translate")) {
+ Float3 value = getFloat3(field);
+ current.addTranslate(description, value);
+ //Log.v(TAG, indent + " translate " + description + toString(value));
+ } else if (fieldName.equals("rotate")) {
+ Float4 value = getFloat4(field);
+ //Log.v(TAG, indent + " rotate " + description + toString(value));
+ Float3 axis = new Float3(value.x, value.y, value.z);
+ current.addRotate(description, axis, value.w);
+ } else if (fieldName.equals("scale")) {
+ Float3 value = getFloat3(field);
+ //Log.v(TAG, indent + " scale " + description + toString(value));
+ current.addScale(description, value);
+ } else if (fieldName.equals("instance_geometry")) {
+ getRenderable(field, current);
+ } else if (fieldName.equals("instance_light")) {
+ updateLight(field, current);
+ } else if (fieldName.equals("instance_camera")) {
+ updateCamera(field, current);
+ } else if (fieldName.equals("node")) {
+ getNode(field, current, indent + " ");
+ }
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ // This will find the actual texture node, which is sometimes hidden behind a sampler
+ // and sometimes referenced directly
+ Texture2D getTexture(String samplerName) {
+ String texName = samplerName;
+
+ // Check to see if the image file is hidden by a sampler surface link combo
+ Element sampler = mDom.getElementById(samplerName);
+ if (sampler != null) {
+ NodeList nl = sampler.getElementsByTagName("source");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String surfaceName = getString(ref);
+ if (surfaceName == null) {
+ return null;
+ }
+
+ Element surface = mDom.getElementById(surfaceName);
+ if (surface == null) {
+ return null;
+ }
+ nl = surface.getElementsByTagName("init_from");
+ if (nl != null && nl.getLength() == 1) {
+ ref = (Element)nl.item(0);
+ texName = getString(ref);
+ }
+ }
+ }
+
+ //Log.v(TAG, "Extracted texture name " + texName);
+ return mImages.get(texName);
+ }
+
+ void extractParams(Element fx, ArrayList<ShaderParam> params) {
+ Node paramNode = fx.getFirstChild();
+ while (paramNode != null) {
+ if (paramNode.getNodeType() == Node.ELEMENT_NODE) {
+ String name = paramNode.getNodeName();
+ // Now find what type it is
+ Node typeNode = paramNode.getFirstChild();
+ while (typeNode != null && typeNode.getNodeType() != Node.ELEMENT_NODE) {
+ typeNode = typeNode.getNextSibling();
+ }
+ String paramType = typeNode.getNodeName();
+ Element typeElem = (Element)typeNode;
+ ShaderParam sceneParam = null;
+ if (paramType.equals("color")) {
+ Float4Param f4p = new Float4Param(name);
+ Float4 value = getFloat4(typeElem);
+ f4p.setValue(value);
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + toString(value));
+ } else if (paramType.equals("float")) {
+ Float4Param f4p = new Float4Param(name);
+ float value = getFloat(typeElem);
+ f4p.setValue(new Float4(value, value, value, value));
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + value);
+ } else if (paramType.equals("texture")) {
+ String samplerName = typeElem.getAttribute("texture");
+ Texture2D tex = getTexture(samplerName);
+ TextureParam texP = new TextureParam(name);
+ texP.setTexture(tex);
+ sceneParam = texP;
+ //Log.v(TAG, "Extracted texture " + tex);
+ }
+ if (sceneParam != null) {
+ params.add(sceneParam);
+ }
+ }
+ paramNode = paramNode.getNextSibling();
+ }
+ }
+
+ private void convertMaterials(Element mat) {
+ String id = mat.getAttribute("id");
+ NodeList nl = mat.getElementsByTagName("instance_effect");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String url = ref.getAttribute("url");
+ ArrayList<ShaderParam> params = mEffectsParams.get(url.substring(1));
+ mEffectsParams.put(id, params);
+ }
+ }
+
+ private void convertGeometries(Element geo) {
+ String id = geo.getAttribute("id");
+ String name = geo.getAttribute("name");
+ if (!id.equals(name)) {
+ mMeshIdNameMap.put(id, name);
+ }
+ }
+
+ private void convertEffects(Element fx) {
+ String id = fx.getAttribute("id");
+ ArrayList<ShaderParam> params = new ArrayList<ShaderParam>();
+
+ NodeList nl = fx.getElementsByTagName("newparam");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ field.setIdAttribute("sid", true);
+ }
+ }
+
+ nl = fx.getElementsByTagName("blinn");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "blinn");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("lambert");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "lambert");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("phong");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "phong");
+ extractParams(field, params);
+ }
+ }
+ mEffectsParams.put(id, params);
+ }
+
+ private void convertLight(Element light) {
+ String name = light.getAttribute("name");
+ String id = light.getAttribute("id");
+
+ // Determine type
+ String[] knownTypes = { "point", "spot", "directional" };
+ final int POINT_LIGHT = 0;
+ final int SPOT_LIGHT = 1;
+ final int DIR_LIGHT = 2;
+ int type = -1;
+ for (int i = 0; i < knownTypes.length; i ++) {
+ NodeList nl = light.getElementsByTagName(knownTypes[i]);
+ if (nl != null && nl.getLength() != 0) {
+ type = i;
+ break;
+ }
+ }
+
+ //Log.v(TAG, "Found Light Type " + type);
+
+ LightBase sceneLight = null;
+ switch (type) {
+ case POINT_LIGHT:
+ sceneLight = new PointLight();
+ break;
+ case SPOT_LIGHT: // TODO: finish light types
+ break;
+ case DIR_LIGHT: // TODO: finish light types
+ break;
+ }
+
+ if (sceneLight == null) {
+ return;
+ }
+
+ Float3 color = getFloat3(light, "color");
+ sceneLight.setColor(color.x, color.y, color.z);
+ sceneLight.setName(name);
+ mScene.appendLight(sceneLight);
+ mLights.put(id, sceneLight);
+
+ //Log.v(TAG, "Light " + name + " color " + toString(color));
+ }
+
+ private void convertCamera(Element camera) {
+ String name = camera.getAttribute("name");
+ String id = camera.getAttribute("id");
+ float fov = 30.0f;
+ if (getString(camera, "yfov") != null) {
+ fov = getFloat(camera, "yfov");
+ } else if(getString(camera, "xfov") != null) {
+ float aspect = getFloat(camera, "aspect_ratio");
+ fov = getFloat(camera, "xfov") / aspect;
+ }
+
+ float near = getFloat(camera, "znear");
+ float far = getFloat(camera, "zfar");
+
+ Camera sceneCamera = new Camera();
+ sceneCamera.setFOV(fov);
+ sceneCamera.setNear(near);
+ sceneCamera.setFar(far);
+ sceneCamera.setName(name);
+ mScene.appendCamera(sceneCamera);
+ mCameras.put(id, sceneCamera);
+ }
+
+ private void convertImage(Element img) {
+ String name = img.getAttribute("name");
+ String id = img.getAttribute("id");
+ String file = getString(img, "init_from");
+
+ Texture2D tex = new Texture2D();
+ tex.setFileName(file);
+ tex.setFileDir(mRootDir);
+ mScene.appendTextures(tex);
+ mImages.put(id, tex);
+ }
+
+ private void getScene(Element scene) {
+ String name = scene.getAttribute("name");
+ String id = scene.getAttribute("id");
+
+ Node childNode = scene.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ String indent = "";
+ getNode((Element)childNode, null, indent);
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ private String getString(Element elem, String name) {
+ String text = null;
+ NodeList nl = elem.getElementsByTagName(name);
+ if (nl != null && nl.getLength() != 0) {
+ text = ((Element)nl.item(0)).getFirstChild().getNodeValue();
+ }
+ return text;
+ }
+
+ private String getString(Element elem) {
+ String text = null;
+ text = elem.getFirstChild().getNodeValue();
+ return text;
+ }
+
+ private int getInt(Element elem, String name) {
+ return Integer.parseInt(getString(elem, name));
+ }
+
+ private float getFloat(Element elem, String name) {
+ return Float.parseFloat(getString(elem, name));
+ }
+
+ private float getFloat(Element elem) {
+ return Float.parseFloat(getString(elem));
+ }
+
+ private Float3 parseFloat3(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ return new Float3(x, y, z);
+ }
+
+ private Float4 parseFloat4(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ float w = Float.parseFloat(st.nextToken());
+ return new Float4(x, y, z, w);
+ }
+
+ private Float3 getFloat3(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat4(valueString);
+ }
+
+ private Float3 getFloat3(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat4(valueString);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java new file mode 100644 index 0000000..301075e --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.BufferedInputStream; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Element.Builder; +import android.renderscript.Font.Style; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; +import com.android.scenegraph.SceneManager.SceneLoadedCallback; + + +public class ColladaScene { + + private String modelName; + private static String TAG = "ColladaScene"; + private final int STATE_LAST_FOCUS = 1; + boolean mLoadFromSD = false; + + SceneLoadedCallback mCallback; + + public ColladaScene(String name, SceneLoadedCallback cb) { + modelName = name; + mCallback = cb; + } + + public void init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + + mLoadFromSD = SceneManager.isSDCardPath(modelName); + + new ColladaLoaderTask().execute(modelName); + } + + private Resources mRes; + private RenderScriptGL mRS; + Scene mActiveScene; + + private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> { + ColladaParser sceneSource; + protected Boolean doInBackground(String... names) { + String rootDir = names[0].substring(0, names[0].lastIndexOf('/') + 1); + long start = System.currentTimeMillis(); + sceneSource = new ColladaParser(); + InputStream is = null; + try { + if (!mLoadFromSD) { + is = mRes.getAssets().open(names[0]); + } else { + File f = new File(names[0]); + is = new BufferedInputStream(new FileInputStream(f)); + } + } catch (IOException e) { + Log.e(TAG, "Could not open collada file"); + return new Boolean(false); + } + long end = System.currentTimeMillis(); + Log.v("TIMER", "Stream load time: " + (end - start)); + + start = System.currentTimeMillis(); + sceneSource.init(is, rootDir); + end = System.currentTimeMillis(); + Log.v("TIMER", "Collada parse time: " + (end - start)); + return new Boolean(true); + } + + protected void onPostExecute(Boolean result) { + mActiveScene = sceneSource.getScene(); + if (mCallback != null) { + mCallback.mLoadedScene = mActiveScene; + mCallback.run(); + } + + String shortName = modelName.substring(0, modelName.lastIndexOf('.')); + new A3DLoaderTask().execute(shortName + ".a3d"); + } + } + + private class A3DLoaderTask extends AsyncTask<String, Void, Boolean> { + protected Boolean doInBackground(String... names) { + long start = System.currentTimeMillis(); + FileA3D model; + if (!mLoadFromSD) { + model = FileA3D.createFromAsset(mRS, mRes.getAssets(), names[0]); + } else { + model = FileA3D.createFromFile(mRS, names[0]); + } + int numModels = model.getIndexEntryCount(); + for (int i = 0; i < numModels; i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + mActiveScene.meshLoaded(entry.getMesh()); + } + } + long end = System.currentTimeMillis(); + Log.v("TIMER", "A3D load time: " + (end - start)); + return new Boolean(true); + } + + protected void onPostExecute(Boolean result) { + } + } + +} + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java new file mode 100644 index 0000000..9274b17 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import com.android.scenegraph.SceneManager; + +import android.renderscript.*; +import android.renderscript.Float3; +import android.renderscript.Matrix4f; +import android.util.Log; + +/** + * @hide + */ +public class CompoundTransform extends Transform { + + public static abstract class Component { + String mName; + CompoundTransform mParent; + int mParentIndex; + protected ScriptField_TransformComponent_s.Item mData; + + Component(int type, String name) { + mData = new ScriptField_TransformComponent_s.Item(); + mData.type = type; + mName = name; + } + + void setNameAlloc() { + RenderScriptGL rs = SceneManager.getRS(); + if (mData.name != null) { + return; + } + mData.name = SceneManager.getCachedAlloc(getName()); + if (mData.name == null) { + mData.name = SceneManager.getStringAsAllocation(rs, getName()); + SceneManager.cacheAlloc(getName(), mData.name); + } + } + + ScriptField_TransformComponent_s.Item getRSData() { + setNameAlloc(); + return mData; + } + + protected void update() { + if (mParent != null) { + mParent.updateRSComponent(this); + } + } + + public String getName() { + return mName; + } + } + + public static class TranslateComponent extends Component { + public TranslateComponent(String name, Float3 translate) { + super(ScriptC_export.const_Transform_TRANSLATE, name); + setValue(translate); + } + public Float3 getValue() { + return new Float3(mData.value.x, mData.value.y, mData.value.z); + } + public void setValue(Float3 val) { + mData.value.x = val.x; + mData.value.y = val.y; + mData.value.z = val.z; + update(); + } + } + + public static class RotateComponent extends Component { + public RotateComponent(String name, Float3 axis, float angle) { + super(ScriptC_export.const_Transform_ROTATE, name); + setAxis(axis); + setAngle(angle); + } + public Float3 getAxis() { + return new Float3(mData.value.x, mData.value.y, mData.value.z); + } + public float getAngle() { + return mData.value.w; + } + public void setAxis(Float3 val) { + mData.value.x = val.x; + mData.value.y = val.y; + mData.value.z = val.z; + update(); + } + public void setAngle(float val) { + mData.value.w = val; + update(); + } + } + + public static class ScaleComponent extends Component { + public ScaleComponent(String name, Float3 scale) { + super(ScriptC_export.const_Transform_SCALE, name); + setValue(scale); + } + public Float3 getValue() { + return new Float3(mData.value.x, mData.value.y, mData.value.z); + } + public void setValue(Float3 val) { + mData.value.x = val.x; + mData.value.y = val.y; + mData.value.z = val.z; + update(); + } + } + + ScriptField_TransformComponent_s mComponentField; + public ArrayList<Component> mTransformComponents; + + public CompoundTransform() { + mTransformComponents = new ArrayList<Component>(); + } + + public TranslateComponent addTranslate(String name, Float3 translate) { + TranslateComponent c = new TranslateComponent(name, translate); + addComponent(c); + return c; + } + + public RotateComponent addRotate(String name, Float3 axis, float angle) { + RotateComponent c = new RotateComponent(name, axis, angle); + addComponent(c); + return c; + } + + public ScaleComponent addScale(String name, Float3 scale) { + ScaleComponent c = new ScaleComponent(name, scale); + addComponent(c); + return c; + } + + public void addComponent(Component c) { + if (c.mParent != null) { + throw new IllegalArgumentException("Transform components may not be shared"); + } + c.mParent = this; + c.mParentIndex = mTransformComponents.size(); + mTransformComponents.add(c); + updateRSComponentAllocation(); + } + + public void setComponent(int index, Component c) { + if (c.mParent != null) { + throw new IllegalArgumentException("Transform components may not be shared"); + } + if (index >= mTransformComponents.size()) { + throw new IllegalArgumentException("Invalid component index"); + } + c.mParent = this; + c.mParentIndex = index; + mTransformComponents.set(index, c); + updateRSComponent(c); + } + + void updateRSComponent(Component c) { + if (mField == null || mComponentField == null) { + return; + } + mComponentField.set(c.getRSData(), c.mParentIndex, true); + mField.set_isDirty(0, 1, true); + } + + void updateRSComponentAllocation() { + if (mField == null) { + return; + } + initLocalData(); + + mField.set_components(0, mTransformData.components, false); + mField.set_isDirty(0, 1, true); + } + + void initLocalData() { + RenderScriptGL rs = SceneManager.getRS(); + int numComponenets = mTransformComponents.size(); + if (numComponenets > 0) { + mComponentField = new ScriptField_TransformComponent_s(rs, numComponenets); + for (int i = 0; i < numComponenets; i ++) { + Component ith = mTransformComponents.get(i); + mComponentField.set(ith.getRSData(), i, false); + } + mComponentField.copyAll(); + + mTransformData.components = mComponentField.getAllocation(); + } + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java new file mode 100644 index 0000000..1502458 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import com.android.scenegraph.Scene; +import com.android.scenegraph.SceneManager; + +import android.renderscript.Element; +import android.renderscript.Float4; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public class Float4Param extends ShaderParam { + private static String TAG = "Float4Param"; + + LightBase mLight; + + public Float4Param(String name) { + super(name); + } + + public Float4Param(String name, float x) { + super(name); + set(x, 0, 0, 0); + } + + public Float4Param(String name, float x, float y) { + super(name); + set(x, y, 0, 0); + } + + public Float4Param(String name, float x, float y, float z) { + super(name); + set(x, y, z, 0); + } + + public Float4Param(String name, float x, float y, float z, float w) { + super(name); + set(x, y, z, w); + } + + void set(float x, float y, float z, float w) { + mData.float_value.x = x; + mData.float_value.y = y; + mData.float_value.z = z; + mData.float_value.w = w; + if (mField != null) { + mField.set_float_value(0, mData.float_value, true); + } + incTimestamp(); + } + + public void setValue(Float4 v) { + set(v.x, v.y, v.z, v.w); + } + + public Float4 getValue() { + return mData.float_value; + } + + public void setLight(LightBase l) { + mLight = l; + if (mField != null) { + mData.light = mLight.getRSData().getAllocation(); + mField.set_light(0, mData.light, true); + } + incTimestamp(); + } + + boolean findLight(String property) { + String indexStr = mParamName.substring(property.length() + 1); + if (indexStr == null) { + Log.e(TAG, "Invalid light index."); + return false; + } + int index = Integer.parseInt(indexStr); + if (index == -1) { + return false; + } + Scene parentScene = SceneManager.getInstance().getActiveScene(); + ArrayList<LightBase> allLights = parentScene.getLights(); + if (index >= allLights.size()) { + return false; + } + mLight = allLights.get(index); + if (mLight == null) { + return false; + } + return true; + } + + int getTypeFromName() { + int paramType = ScriptC_export.const_ShaderParam_FLOAT4_DATA; + if (mParamName.equalsIgnoreCase(cameraPos)) { + paramType = ScriptC_export.const_ShaderParam_FLOAT4_CAMERA_POS; + } else if(mParamName.equalsIgnoreCase(cameraDir)) { + paramType = ScriptC_export.const_ShaderParam_FLOAT4_CAMERA_DIR; + } else if(mParamName.startsWith(lightColor) && findLight(lightColor)) { + paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_COLOR; + } else if(mParamName.startsWith(lightPos) && findLight(lightPos)) { + paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_POS; + } else if(mParamName.startsWith(lightDir) && findLight(lightDir)) { + paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_DIR; + } + return paramType; + } + + void initLocalData() { + mData.type = getTypeFromName(); + if (mCamera != null) { + mData.camera = mCamera.getRSData().getAllocation(); + } + if (mLight != null) { + mData.light = mLight.getRSData().getAllocation(); + } + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java new file mode 100644 index 0000000..8a468db --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import com.android.scenegraph.TextureBase; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramFragment.Builder; +import android.util.Log; + +/** + * @hide + */ +public class FragmentShader extends Shader { + ProgramFragment mProgram; + ScriptField_FragmentShader_s mField; + + public static class Builder { + + FragmentShader mShader; + ProgramFragment.Builder mBuilder; + + public Builder(RenderScriptGL rs) { + mShader = new FragmentShader(); + mBuilder = new ProgramFragment.Builder(rs); + } + + public Builder setShader(Resources resources, int resourceID) { + mBuilder.setShader(resources, resourceID); + return this; + } + + public Builder setShader(String code) { + mBuilder.setShader(code); + return this; + } + + public Builder setObjectConst(Type type) { + mShader.mPerObjConstants = type; + return this; + } + + public Builder setShaderConst(Type type) { + mShader.mPerShaderConstants = type; + return this; + } + + public Builder addShaderTexture(Program.TextureType texType, String name) { + mShader.mShaderTextureNames.add(name); + mShader.mShaderTextureTypes.add(texType); + return this; + } + + public Builder addTexture(Program.TextureType texType, String name) { + mShader.mTextureNames.add(name); + mShader.mTextureTypes.add(texType); + return this; + } + + public FragmentShader create() { + if (mShader.mPerShaderConstants != null) { + mBuilder.addConstant(mShader.mPerShaderConstants); + } + if (mShader.mPerObjConstants != null) { + mBuilder.addConstant(mShader.mPerObjConstants); + } + for (int i = 0; i < mShader.mTextureTypes.size(); i ++) { + mBuilder.addTexture(mShader.mTextureTypes.get(i), + mShader.mTextureNames.get(i)); + } + for (int i = 0; i < mShader.mShaderTextureTypes.size(); i ++) { + mBuilder.addTexture(mShader.mShaderTextureTypes.get(i), + mShader.mShaderTextureNames.get(i)); + } + + mShader.mProgram = mBuilder.create(); + return mShader; + } + } + + public ProgramFragment getProgram() { + return mProgram; + } + + ScriptField_ShaderParam_s getTextureParams() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + ArrayList<ScriptField_ShaderParam_s.Item> paramList; + paramList = new ArrayList<ScriptField_ShaderParam_s.Item>(); + + int shaderTextureStart = mTextureTypes.size(); + for (int i = 0; i < mShaderTextureNames.size(); i ++) { + ShaderParam sp = mSourceParams.get(mShaderTextureNames.get(i)); + if (sp != null && sp instanceof TextureParam) { + TextureParam p = (TextureParam)sp; + ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item(); + paramRS.bufferOffset = shaderTextureStart + i; + paramRS.transformTimestamp = 0; + paramRS.dataTimestamp = 0; + paramRS.data = p.getRSData().getAllocation(); + paramList.add(paramRS); + } + } + + ScriptField_ShaderParam_s rsParams = null; + int paramCount = paramList.size(); + if (paramCount != 0) { + rsParams = new ScriptField_ShaderParam_s(rs, paramCount); + for (int i = 0; i < paramCount; i++) { + rsParams.set(paramList.get(i), i, false); + } + rsParams.copyAll(); + } + return rsParams; + } + + ScriptField_FragmentShader_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + ScriptField_FragmentShader_s.Item item = new ScriptField_FragmentShader_s.Item(); + item.program = mProgram; + + ScriptField_ShaderParam_s texParams = getTextureParams(); + if (texParams != null) { + item.shaderTextureParams = texParams.getAllocation(); + } + + linkConstants(rs); + if (mPerShaderConstants != null) { + item.shaderConst = mConstantBuffer; + item.shaderConstParams = mConstantBufferParams.getAllocation(); + mProgram.bindConstants(item.shaderConst, 0); + } + + item.objectConstIndex = -1; + if (mPerObjConstants != null) { + item.objectConstIndex = mPerShaderConstants != null ? 1 : 0; + } + + mField = new ScriptField_FragmentShader_s(rs, 1); + mField.set(item, 0, true); + return mField; + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java new file mode 100644 index 0000000..8f5e2e7 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.Float3; +import android.renderscript.Float4; +import android.renderscript.Matrix4f; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public abstract class LightBase extends SceneGraphBase { + static final int RS_LIGHT_POINT = 0; + static final int RS_LIGHT_DIRECTIONAL = 1; + + ScriptField_Light_s mField; + ScriptField_Light_s.Item mFieldData; + Transform mTransform; + Float4 mColor; + float mIntensity; + public LightBase() { + mColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f); + mIntensity = 1.0f; + } + + public void setTransform(Transform t) { + mTransform = t; + updateRSData(); + } + + public void setColor(float r, float g, float b) { + mColor.x = r; + mColor.y = g; + mColor.z = b; + updateRSData(); + } + + public void setColor(Float3 c) { + setColor(c.x, c.y, c.z); + } + + public void setIntensity(float i) { + mIntensity = i; + updateRSData(); + } + + public void setName(String n) { + super.setName(n); + updateRSData(); + } + + protected void updateRSData() { + if (mField == null) { + return; + } + RenderScriptGL rs = SceneManager.getRS(); + mFieldData.transformMatrix = mTransform.getRSData().getAllocation(); + mFieldData.name = getNameAlloc(rs); + mFieldData.color = mColor; + mFieldData.intensity = mIntensity; + + initLocalData(); + + mField.set(mFieldData, 0, true); + } + + abstract void initLocalData(); + + ScriptField_Light_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + if (mField == null) { + mField = new ScriptField_Light_s(rs, 1); + mFieldData = new ScriptField_Light_s.Item(); + } + + updateRSData(); + + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java new file mode 100644 index 0000000..6d70bc9 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.Matrix4f; +import android.util.Log; + +/** + * @hide + */ +public class MatrixTransform extends Transform { + + Matrix4f mLocalMatrix; + public MatrixTransform() { + mLocalMatrix = new Matrix4f(); + } + + public void setMatrix(Matrix4f matrix) { + mLocalMatrix = matrix; + updateRSData(); + } + + public Matrix4f getMatrix() { + return new Matrix4f(mLocalMatrix.getArray()); + } + + void initLocalData() { + mTransformData.localMat = mLocalMatrix; + } + + void updateRSData() { + if (mField == null) { + return; + } + mField.set_localMat(0, mLocalMatrix, false); + mField.set_isDirty(0, 1, true); + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java new file mode 100644 index 0000000..574bafc --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.util.Log; + +/** + * @hide + */ +public class PointLight extends LightBase { + public PointLight() { + } + + void initLocalData() { + mFieldData.type = RS_LIGHT_POINT; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java new file mode 100644 index 0000000..02fd69d --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.util.Log; + +import android.renderscript.*; +import android.content.res.Resources; + +/** + * @hide + */ +public class RenderPass extends SceneGraphBase { + + TextureRenderTarget mColorTarget; + Float4 mClearColor; + boolean mShouldClearColor; + + TextureRenderTarget mDepthTarget; + float mClearDepth; + boolean mShouldClearDepth; + + ArrayList<RenderableBase> mObjectsToDraw; + + Camera mCamera; + + ScriptField_RenderPass_s.Item mRsField; + + public RenderPass() { + mObjectsToDraw = new ArrayList<RenderableBase>(); + mClearColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f); + mShouldClearColor = true; + mClearDepth = 1.0f; + mShouldClearDepth = true; + } + + public void appendRenderable(Renderable d) { + mObjectsToDraw.add(d); + } + + public void setCamera(Camera c) { + mCamera = c; + } + + public void setColorTarget(TextureRenderTarget colorTarget) { + mColorTarget = colorTarget; + } + public void setClearColor(Float4 clearColor) { + mClearColor = clearColor; + } + public void setShouldClearColor(boolean shouldClearColor) { + mShouldClearColor = shouldClearColor; + } + + public void setDepthTarget(TextureRenderTarget depthTarget) { + mDepthTarget = depthTarget; + } + public void setClearDepth(float clearDepth) { + mClearDepth = clearDepth; + } + public void setShouldClearDepth(boolean shouldClearDepth) { + mShouldClearDepth = shouldClearDepth; + } + + public ArrayList<RenderableBase> getRenderables() { + return mObjectsToDraw; + } + + ScriptField_RenderPass_s.Item getRsField(RenderScriptGL rs, Resources res) { + if (mRsField != null) { + return mRsField; + } + + mRsField = new ScriptField_RenderPass_s.Item(); + if (mColorTarget != null) { + mRsField.color_target = mColorTarget.getRsData(true).get_texture(0); + } + if (mColorTarget != null) { + mRsField.depth_target = mDepthTarget.getRsData(true).get_texture(0); + } + mRsField.camera = mCamera != null ? mCamera.getRSData().getAllocation() : null; + + if (mObjectsToDraw.size() != 0) { + Allocation drawableData = Allocation.createSized(rs, + Element.ALLOCATION(rs), + mObjectsToDraw.size()); + Allocation[] drawableAllocs = new Allocation[mObjectsToDraw.size()]; + for (int i = 0; i < mObjectsToDraw.size(); i ++) { + Renderable dI = (Renderable)mObjectsToDraw.get(i); + drawableAllocs[i] = dI.getRsField(rs, res).getAllocation(); + } + drawableData.copyFrom(drawableAllocs); + mRsField.objects = drawableData; + } + + mRsField.clear_color = mClearColor; + mRsField.clear_depth = mClearDepth; + mRsField.should_clear_color = mShouldClearColor; + mRsField.should_clear_depth = mShouldClearDepth; + return mRsField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java new file mode 100644 index 0000000..c08a722 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; +import android.content.res.Resources; + +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramRaster; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.RSRuntimeException; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public class RenderState extends SceneGraphBase { + VertexShader mVertex; + FragmentShader mFragment; + ProgramStore mStore; + ProgramRaster mRaster; + + ScriptField_RenderState_s mField; + + public RenderState(VertexShader pv, + FragmentShader pf, + ProgramStore ps, + ProgramRaster pr) { + mVertex = pv; + mFragment = pf; + mStore = ps; + mRaster = pr; + } + + public RenderState(RenderState r) { + mVertex = r.mVertex; + mFragment = r.mFragment; + mStore = r.mStore; + mRaster = r.mRaster; + } + + public void setProgramVertex(VertexShader pv) { + mVertex = pv; + updateRSData(); + } + + public void setProgramFragment(FragmentShader pf) { + mFragment = pf; + updateRSData(); + } + + public void setProgramStore(ProgramStore ps) { + mStore = ps; + updateRSData(); + } + + public void setProgramRaster(ProgramRaster pr) { + mRaster = pr; + updateRSData(); + } + + void updateRSData() { + if (mField == null) { + return; + } + ScriptField_RenderState_s.Item item = new ScriptField_RenderState_s.Item(); + item.pv = mVertex.getRSData().getAllocation(); + item.pf = mFragment.getRSData().getAllocation(); + item.ps = mStore; + item.pr = mRaster; + + mField.set(item, 0, true); + } + + public ScriptField_RenderState_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + + mField = new ScriptField_RenderState_s(rs, 1); + updateRSData(); + + return mField; + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java new file mode 100644 index 0000000..9266f30 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import com.android.scenegraph.Float4Param; +import com.android.scenegraph.MatrixTransform; +import com.android.scenegraph.SceneManager; +import com.android.scenegraph.ShaderParam; +import com.android.scenegraph.TransformParam; + +import android.content.res.Resources; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Element.DataType; +import android.renderscript.Matrix4f; +import android.renderscript.Mesh; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public class Renderable extends RenderableBase { + HashMap<String, ShaderParam> mSourceParams; + + RenderState mRenderState; + Transform mTransform; + + String mMeshName; + String mMeshIndexName; + + public String mMaterialName; + + ScriptField_Renderable_s mField; + ScriptField_Renderable_s.Item mData; + + public Renderable() { + mSourceParams = new HashMap<String, ShaderParam>(); + mData = new ScriptField_Renderable_s.Item(); + } + + public void setCullType(int cull) { + mData.cullType = cull; + } + + public void setRenderState(RenderState renderState) { + mRenderState = renderState; + if (mField != null) { + RenderScriptGL rs = SceneManager.getRS(); + updateFieldItem(rs); + mField.set(mData, 0, true); + } + } + + public void setMesh(Mesh mesh) { + mData.mesh = mesh; + if (mField != null) { + mField.set_mesh(0, mData.mesh, true); + } + } + + public void setMesh(String mesh, String indexName) { + mMeshName = mesh; + mMeshIndexName = indexName; + } + + public void setMaterialName(String name) { + mMaterialName = name; + } + + public Transform getTransform() { + return mTransform; + } + + public void setTransform(Transform t) { + mTransform = t; + if (mField != null) { + RenderScriptGL rs = SceneManager.getRS(); + updateFieldItem(rs); + mField.set(mData, 0, true); + } + } + + public void appendSourceParams(ShaderParam p) { + mSourceParams.put(p.getParamName(), p); + // Possibly lift this restriction later + if (mField != null) { + throw new RuntimeException("Can't add source params to objects that are rendering"); + } + } + + public void resolveMeshData(Mesh mesh) { + mData.mesh = mesh; + if (mData.mesh == null) { + Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName); + return; + } + int subIndexCount = mData.mesh.getPrimitiveCount(); + if (subIndexCount == 1 || mMeshIndexName == null) { + mData.meshIndex = 0; + } else { + for (int i = 0; i < subIndexCount; i ++) { + if (mData.mesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) { + mData.meshIndex = i; + break; + } + } + } + if (mField != null) { + mField.set(mData, 0, true); + } + } + + void updateTextures(RenderScriptGL rs) { + Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator(); + int paramIndex = 0; + while (allParamsIter.hasNext()) { + ShaderParam sp = allParamsIter.next(); + if (sp instanceof TextureParam) { + TextureParam p = (TextureParam)sp; + TextureBase tex = p.getTexture(); + if (tex != null) { + mData.pf_textures[paramIndex++] = tex.getRsData(false).getAllocation(); + } + } + } + ProgramFragment pf = mRenderState.mFragment.mProgram; + mData.pf_num_textures = pf != null ? Math.min(pf.getTextureCount(), paramIndex) : 0; + if (mField != null) { + mField.set_pf_textures(0, mData.pf_textures, true); + mField.set_pf_num_textures(0, mData.pf_num_textures, true); + } + } + + public void setVisible(boolean vis) { + mData.cullType = vis ? 0 : 2; + if (mField != null) { + mField.set_cullType(0, mData.cullType, true); + } + } + + ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) { + if (mField != null) { + return mField; + } + updateFieldItem(rs); + updateTextures(rs); + + mField = new ScriptField_Renderable_s(rs, 1); + mField.set(mData, 0, true); + + return mField; + } + + void updateVertexConstants(RenderScriptGL rs) { + Allocation pvParams = null, vertexConstants = null; + VertexShader pv = mRenderState.mVertex; + if (pv != null && pv.getObjectConstants() != null) { + vertexConstants = Allocation.createTyped(rs, pv.getObjectConstants()); + Element vertexConst = vertexConstants.getType().getElement(); + pvParams = ShaderParam.fillInParams(vertexConst, mSourceParams, + mTransform).getAllocation(); + } + mData.pv_const = vertexConstants; + mData.pv_constParams = pvParams; + } + + void updateFragmentConstants(RenderScriptGL rs) { + Allocation pfParams = null, fragmentConstants = null; + FragmentShader pf = mRenderState.mFragment; + if (pf != null && pf.getObjectConstants() != null) { + fragmentConstants = Allocation.createTyped(rs, pf.getObjectConstants()); + Element fragmentConst = fragmentConstants.getType().getElement(); + pfParams = ShaderParam.fillInParams(fragmentConst, mSourceParams, + mTransform).getAllocation(); + } + mData.pf_const = fragmentConstants; + mData.pf_constParams = pfParams; + } + + void updateFieldItem(RenderScriptGL rs) { + if (mRenderState == null) { + mRenderState = SceneManager.getDefaultState(); + } + if (mTransform == null) { + mTransform = SceneManager.getDefaultTransform(); + } + updateVertexConstants(rs); + updateFragmentConstants(rs); + + mData.transformMatrix = mTransform.getRSData().getAllocation(); + + mData.name = getNameAlloc(rs); + mData.render_state = mRenderState.getRSData().getAllocation(); + mData.bVolInitialized = 0; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java new file mode 100644 index 0000000..74535dd --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.util.Log; + +/** + * @hide + */ +public class RenderableBase extends SceneGraphBase { + public RenderableBase() { + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java new file mode 100644 index 0000000..590bbab --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.util.Log; + +/** + * @hide + */ +public class RenderableGroup extends RenderableBase { + + ArrayList<RenderableBase> mChildren; + + public RenderableGroup() { + mChildren = new ArrayList<RenderableBase>(); + } + + public void appendChildren(RenderableBase d) { + mChildren.add(d); + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java new file mode 100644 index 0000000..27336ab --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java @@ -0,0 +1,373 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.android.scenegraph.Camera; +import com.android.scenegraph.CompoundTransform; +import com.android.scenegraph.RenderPass; +import com.android.scenegraph.Renderable; +import com.android.scenegraph.SceneManager; +import com.android.scenegraph.TextureBase; + +import android.content.res.Resources; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Mesh; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public class Scene extends SceneGraphBase { + private static String TIMER_TAG = "TIMER"; + + CompoundTransform mRootTransforms; + HashMap<String, Transform> mTransformMap; + ArrayList<RenderPass> mRenderPasses; + ArrayList<LightBase> mLights; + ArrayList<Camera> mCameras; + ArrayList<FragmentShader> mFragmentShaders; + ArrayList<VertexShader> mVertexShaders; + ArrayList<RenderableBase> mRenderables; + HashMap<String, RenderableBase> mRenderableMap; + ArrayList<Texture2D> mTextures; + + HashMap<String, ArrayList<Renderable> > mRenderableMeshMap; + + // RS Specific stuff + ScriptField_SgTransform mTransformRSData; + + RenderScriptGL mRS; + Resources mRes; + + ScriptField_RenderPass_s mRenderPassAlloc; + + public Scene() { + mRenderPasses = new ArrayList<RenderPass>(); + mLights = new ArrayList<LightBase>(); + mCameras = new ArrayList<Camera>(); + mFragmentShaders = new ArrayList<FragmentShader>(); + mVertexShaders = new ArrayList<VertexShader>(); + mRenderables = new ArrayList<RenderableBase>(); + mRenderableMap = new HashMap<String, RenderableBase>(); + mRenderableMeshMap = new HashMap<String, ArrayList<Renderable> >(); + mTextures = new ArrayList<Texture2D>(); + mRootTransforms = new CompoundTransform(); + mRootTransforms.setName("_scene_root_"); + mTransformMap = new HashMap<String, Transform>(); + } + + public void appendTransform(Transform t) { + if (t == null) { + throw new RuntimeException("Adding null object"); + } + mRootTransforms.appendChild(t); + } + + public CompoundTransform appendNewCompoundTransform() { + CompoundTransform t = new CompoundTransform(); + appendTransform(t); + return t; + } + + public MatrixTransform appendNewMatrixTransform() { + MatrixTransform t = new MatrixTransform(); + appendTransform(t); + return t; + } + + // temporary + public void addToTransformMap(Transform t) { + mTransformMap.put(t.getName(), t); + } + + public Transform getTransformByName(String name) { + return mTransformMap.get(name); + } + + public void appendRenderPass(RenderPass p) { + if (p == null) { + throw new RuntimeException("Adding null object"); + } + mRenderPasses.add(p); + } + + public RenderPass appendNewRenderPass() { + RenderPass p = new RenderPass(); + appendRenderPass(p); + return p; + } + + public void clearRenderPasses() { + mRenderPasses.clear(); + } + + public void appendLight(LightBase l) { + if (l == null) { + throw new RuntimeException("Adding null object"); + } + mLights.add(l); + } + + public void appendCamera(Camera c) { + if (c == null) { + throw new RuntimeException("Adding null object"); + } + mCameras.add(c); + } + + public Camera appendNewCamera() { + Camera c = new Camera(); + appendCamera(c); + return c; + } + + public void appendShader(FragmentShader f) { + if (f == null) { + throw new RuntimeException("Adding null object"); + } + mFragmentShaders.add(f); + } + + public void appendShader(VertexShader v) { + if (v == null) { + throw new RuntimeException("Adding null object"); + } + mVertexShaders.add(v); + } + + public ArrayList<Camera> getCameras() { + return mCameras; + } + + public ArrayList<LightBase> getLights() { + return mLights; + } + + public void appendRenderable(RenderableBase d) { + if (d == null) { + throw new RuntimeException("Adding null object"); + } + mRenderables.add(d); + if (d.getName() != null) { + mRenderableMap.put(d.getName(), d); + } + } + + public Renderable appendNewRenderable() { + Renderable r = new Renderable(); + appendRenderable(r); + return r; + } + + public ArrayList<RenderableBase> getRenderables() { + return mRenderables; + } + + public RenderableBase getRenderableByName(String name) { + return mRenderableMap.get(name); + } + + public void appendTextures(Texture2D tex) { + if (tex == null) { + throw new RuntimeException("Adding null object"); + } + mTextures.add(tex); + } + + public void assignRenderStateToMaterial(RenderState renderState, String regex) { + Pattern pattern = Pattern.compile(regex); + int numRenderables = mRenderables.size(); + for (int i = 0; i < numRenderables; i ++) { + Renderable shape = (Renderable)mRenderables.get(i); + Matcher m = pattern.matcher(shape.mMaterialName); + if (m.find()) { + shape.setRenderState(renderState); + } + } + } + + public void assignRenderState(RenderState renderState) { + int numRenderables = mRenderables.size(); + for (int i = 0; i < numRenderables; i ++) { + Renderable shape = (Renderable)mRenderables.get(i); + shape.setRenderState(renderState); + } + } + + public void meshLoaded(Mesh m) { + ArrayList<Renderable> entries = mRenderableMeshMap.get(m.getName()); + int numEntries = entries.size(); + for (int i = 0; i < numEntries; i++) { + Renderable d = entries.get(i); + d.resolveMeshData(m); + } + } + + void addToMeshMap(Renderable d) { + ArrayList<Renderable> entries = mRenderableMeshMap.get(d.mMeshName); + if (entries == null) { + entries = new ArrayList<Renderable>(); + mRenderableMeshMap.put(d.mMeshName, entries); + } + entries.add(d); + } + + public void destroyRS() { + SceneManager sceneManager = SceneManager.getInstance(); + mTransformRSData = null; + sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData); + sceneManager.mRenderLoop.set_gRenderableObjects(null); + mRenderPassAlloc = null; + sceneManager.mRenderLoop.set_gRenderPasses(null); + sceneManager.mRenderLoop.bind_gFrontToBack(null); + sceneManager.mRenderLoop.bind_gBackToFront(null); + sceneManager.mRenderLoop.set_gCameras(null); + + mTransformMap = null; + mRenderPasses = null; + mLights = null; + mCameras = null; + mRenderables = null; + mRenderableMap = null; + mTextures = null; + mRenderableMeshMap = null; + mRootTransforms = null; + } + + public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) { + if (mRenderPasses.size() != 0) { + mRenderPassAlloc = new ScriptField_RenderPass_s(mRS, mRenderPasses.size()); + for (int i = 0; i < mRenderPasses.size(); i ++) { + mRenderPassAlloc.set(mRenderPasses.get(i).getRsField(mRS, mRes), i, false); + } + mRenderPassAlloc.copyAll(); + sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation()); + } + } + + private void addDrawables(RenderScriptGL rs, Resources res, SceneManager sceneManager) { + Allocation drawableData = Allocation.createSized(rs, + Element.ALLOCATION(rs), + mRenderables.size()); + Allocation[] drawableAllocs = new Allocation[mRenderables.size()]; + for (int i = 0; i < mRenderables.size(); i ++) { + Renderable dI = (Renderable)mRenderables.get(i); + addToMeshMap(dI); + drawableAllocs[i] = dI.getRsField(rs, res).getAllocation(); + } + drawableData.copyFrom(drawableAllocs); + sceneManager.mRenderLoop.set_gRenderableObjects(drawableData); + + initRenderPassRS(rs, sceneManager); + } + + private void addShaders(RenderScriptGL rs, Resources res, SceneManager sceneManager) { + if (mVertexShaders.size() > 0) { + Allocation shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs), + mVertexShaders.size()); + Allocation[] shaderAllocs = new Allocation[mVertexShaders.size()]; + for (int i = 0; i < mVertexShaders.size(); i ++) { + VertexShader sI = mVertexShaders.get(i); + shaderAllocs[i] = sI.getRSData().getAllocation(); + } + shaderData.copyFrom(shaderAllocs); + sceneManager.mRenderLoop.set_gVertexShaders(shaderData); + } + + if (mFragmentShaders.size() > 0) { + Allocation shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs), + mFragmentShaders.size()); + Allocation[] shaderAllocs = new Allocation[mFragmentShaders.size()]; + for (int i = 0; i < mFragmentShaders.size(); i ++) { + FragmentShader sI = mFragmentShaders.get(i); + shaderAllocs[i] = sI.getRSData().getAllocation(); + } + shaderData.copyFrom(shaderAllocs); + sceneManager.mRenderLoop.set_gFragmentShaders(shaderData); + } + } + + public void initRS() { + SceneManager sceneManager = SceneManager.getInstance(); + mRS = SceneManager.getRS(); + mRes = SceneManager.getRes(); + long start = System.currentTimeMillis(); + mTransformRSData = mRootTransforms.getRSData(); + long end = System.currentTimeMillis(); + Log.v(TIMER_TAG, "Transform init time: " + (end - start)); + + start = System.currentTimeMillis(); + + sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData); + end = System.currentTimeMillis(); + Log.v(TIMER_TAG, "Script init time: " + (end - start)); + + start = System.currentTimeMillis(); + addDrawables(mRS, mRes, sceneManager); + end = System.currentTimeMillis(); + Log.v(TIMER_TAG, "Renderable init time: " + (end - start)); + + addShaders(mRS, mRes, sceneManager); + + Allocation opaqueBuffer = null; + if (mRenderables.size() > 0) { + opaqueBuffer = Allocation.createSized(mRS, Element.U32(mRS), mRenderables.size()); + } + Allocation transparentBuffer = null; + if (mRenderables.size() > 0) { + transparentBuffer = Allocation.createSized(mRS, Element.U32(mRS), mRenderables.size()); + } + + sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer); + sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer); + + if (mCameras.size() > 0) { + Allocation cameraData; + cameraData = Allocation.createSized(mRS, Element.ALLOCATION(mRS), mCameras.size()); + Allocation[] cameraAllocs = new Allocation[mCameras.size()]; + for (int i = 0; i < mCameras.size(); i ++) { + cameraAllocs[i] = mCameras.get(i).getRSData().getAllocation(); + } + cameraData.copyFrom(cameraAllocs); + sceneManager.mRenderLoop.set_gCameras(cameraData); + } + + if (mLights.size() > 0) { + Allocation lightData = Allocation.createSized(mRS, + Element.ALLOCATION(mRS), + mLights.size()); + Allocation[] lightAllocs = new Allocation[mLights.size()]; + for (int i = 0; i < mLights.size(); i ++) { + lightAllocs[i] = mLights.get(i).getRSData().getAllocation(); + } + lightData.copyFrom(lightAllocs); + sceneManager.mRenderLoop.set_gLights(lightData); + } + } +} + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java new file mode 100644 index 0000000..412ffbf --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import com.android.scenegraph.SceneManager; + +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.RSRuntimeException; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public abstract class SceneGraphBase { + String mName; + Allocation mNameAlloc; + public void setName(String n) { + mName = n; + mNameAlloc = null; + } + + public String getName() { + return mName; + } + + Allocation getNameAlloc(RenderScriptGL rs) { + if (mNameAlloc == null) { + mNameAlloc = SceneManager.getStringAsAllocation(rs, getName()); + } + return mNameAlloc; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java new file mode 100644 index 0000000..4ff2c8b --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java @@ -0,0 +1,503 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Writer; +import java.lang.Math; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.android.scenegraph.Camera; +import com.android.scenegraph.FragmentShader; +import com.android.scenegraph.MatrixTransform; +import com.android.scenegraph.Scene; +import com.android.scenegraph.VertexShader; +import com.android.testapp.R; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Mesh; +import android.renderscript.RenderScriptGL; +import android.util.Log; +import android.view.SurfaceHolder; + +/** + * @hide + */ +public class SceneManager extends SceneGraphBase { + + HashMap<String, Allocation> mAllocationMap; + + ScriptC_render mRenderLoop; + ScriptC mCameraScript; + ScriptC mLightScript; + ScriptC mObjectParamsScript; + ScriptC mFragmentParamsScript; + ScriptC mVertexParamsScript; + ScriptC mCullScript; + ScriptC_transform mTransformScript; + ScriptC_export mExportScript; + + RenderScriptGL mRS; + Resources mRes; + Mesh mQuad; + int mWidth; + int mHeight; + + Scene mActiveScene; + private static SceneManager sSceneManager; + + private Allocation mDefault2D; + private Allocation mDefaultCube; + + private FragmentShader mColor; + private FragmentShader mTexture; + private VertexShader mDefaultVertex; + + private RenderState mDefaultState; + private Transform mDefaultTransform; + + private static Allocation getDefault(boolean isCube) { + final int dimension = 4; + final int bytesPerPixel = 4; + int arraySize = dimension * dimension * bytesPerPixel; + + RenderScriptGL rs = sSceneManager.mRS; + Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs)); + b.setX(dimension).setY(dimension); + if (isCube) { + b.setFaces(true); + arraySize *= 6; + } + Type bitmapType = b.create(); + + Allocation.MipmapControl mip = Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE; + int usage = Allocation.USAGE_GRAPHICS_TEXTURE; + Allocation defaultImage = Allocation.createTyped(rs, bitmapType, mip, usage); + + byte imageData[] = new byte[arraySize]; + defaultImage.copyFrom(imageData); + return defaultImage; + } + + static Allocation getDefaultTex2D() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mDefault2D == null) { + sSceneManager.mDefault2D = getDefault(false); + } + return sSceneManager.mDefault2D; + } + + static Allocation getDefaultTexCube() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mDefaultCube == null) { + sSceneManager.mDefaultCube = getDefault(true); + } + return sSceneManager.mDefaultCube; + } + + public static boolean isSDCardPath(String path) { + int sdCardIndex = path.indexOf("sdcard/"); + // We are looking for /sdcard/ or sdcard/ + if (sdCardIndex == 0 || sdCardIndex == 1) { + return true; + } + sdCardIndex = path.indexOf("mnt/sdcard/"); + if (sdCardIndex == 0 || sdCardIndex == 1) { + return true; + } + return false; + } + + static Bitmap loadBitmap(String name, Resources res) { + InputStream is = null; + boolean loadFromSD = isSDCardPath(name); + try { + if (!loadFromSD) { + is = res.getAssets().open(name); + } else { + File f = new File(name); + is = new BufferedInputStream(new FileInputStream(f)); + } + } catch (IOException e) { + Log.e("ImageLoaderTask", " Message: " + e.getMessage()); + return null; + } + + Bitmap b = BitmapFactory.decodeStream(is); + try { + is.close(); + } catch (IOException e) { + Log.e("ImageLoaderTask", " Message: " + e.getMessage()); + } + return b; + } + + static Allocation createFromBitmap(Bitmap b, RenderScriptGL rs, boolean isCube) { + if (b == null) { + return null; + } + MipmapControl mip = MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE; + int usage = Allocation.USAGE_GRAPHICS_TEXTURE; + if (isCube) { + return Allocation.createCubemapFromBitmap(rs, b, mip, usage); + } + return Allocation.createFromBitmap(rs, b, mip, usage); + } + + public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) { + return createFromBitmap(loadBitmap(name, res), rs, true); + } + + public static Allocation loadCubemap(int id, RenderScriptGL rs, Resources res) { + return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, true); + } + + public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) { + return createFromBitmap(loadBitmap(name, res), rs, false); + } + + public static Allocation loadTexture2D(int id, RenderScriptGL rs, Resources res) { + return createFromBitmap(BitmapFactory.decodeResource(res, id), rs, false); + } + + public static ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) { + ProgramStore.Builder builder = new ProgramStore.Builder(rs); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE); + builder.setDitherEnabled(false); + builder.setDepthMaskEnabled(false); + return builder.create(); + } + + static Allocation getStringAsAllocation(RenderScript rs, String str) { + if (str == null) { + return null; + } + if (str.length() == 0) { + return null; + } + byte[] allocArray = null; + byte[] nullChar = new byte[1]; + nullChar[0] = 0; + try { + allocArray = str.getBytes("UTF-8"); + Allocation alloc = Allocation.createSized(rs, Element.U8(rs), + allocArray.length + 1, + Allocation.USAGE_SCRIPT); + alloc.copy1DRangeFrom(0, allocArray.length, allocArray); + alloc.copy1DRangeFrom(allocArray.length, 1, nullChar); + return alloc; + } + catch (Exception e) { + throw new RSRuntimeException("Could not convert string to utf-8."); + } + } + + static Allocation getCachedAlloc(String str) { + if (sSceneManager == null) { + throw new RuntimeException("Scene manager not initialized"); + } + return sSceneManager.mAllocationMap.get(str); + } + + static void cacheAlloc(String str, Allocation alloc) { + if (sSceneManager == null) { + throw new RuntimeException("Scene manager not initialized"); + } + sSceneManager.mAllocationMap.put(str, alloc); + } + + public static class SceneLoadedCallback implements Runnable { + public Scene mLoadedScene; + public String mName; + public void run() { + } + } + + public Scene getActiveScene() { + return mActiveScene; + } + + public void setActiveScene(Scene s) { + mActiveScene = s; + + if (mActiveScene == null) { + return; + } + + // Do some sanity checking + if (mActiveScene.getCameras().size() == 0) { + Matrix4f camPos = new Matrix4f(); + camPos.translate(0, 0, 10); + MatrixTransform cameraTransform = new MatrixTransform(); + cameraTransform.setName("_DefaultCameraTransform"); + cameraTransform.setMatrix(camPos); + mActiveScene.appendTransform(cameraTransform); + Camera cam = new Camera(); + cam.setName("_DefaultCamera"); + cam.setTransform(cameraTransform); + mActiveScene.appendCamera(cam); + } + + mActiveScene.appendShader(getDefaultVS()); + mActiveScene.appendTransform(getDefaultTransform()); + } + + static RenderScriptGL getRS() { + if (sSceneManager == null) { + return null; + } + return sSceneManager.mRS; + } + + static Resources getRes() { + if (sSceneManager == null) { + return null; + } + return sSceneManager.mRes; + } + + // Provides the folowing inputs to fragment shader + // Assigned by default if nothing is present + // vec3 varWorldPos; + // vec3 varWorldNormal; + // vec2 varTex0; + public static VertexShader getDefaultVS() { + if (sSceneManager == null) { + return null; + } + + if (sSceneManager.mDefaultVertex == null) { + RenderScriptGL rs = getRS(); + Element.Builder b = new Element.Builder(rs); + b.add(Element.MATRIX_4X4(rs), "model"); + Type.Builder objConstBuilder = new Type.Builder(rs, b.create()); + + b = new Element.Builder(rs); + b.add(Element.MATRIX_4X4(rs), "viewProj"); + Type.Builder shaderConstBuilder = new Type.Builder(rs, b.create()); + + b = new Element.Builder(rs); + b.add(Element.F32_4(rs), "position"); + b.add(Element.F32_2(rs), "texture0"); + b.add(Element.F32_3(rs), "normal"); + Element defaultIn = b.create(); + + final String code = "\n" + + "varying vec3 varWorldPos;\n" + + "varying vec3 varWorldNormal;\n" + + "varying vec2 varTex0;\n" + + "void main() {" + + " vec4 objPos = ATTRIB_position;\n" + + " vec4 worldPos = UNI_model * objPos;\n" + + " gl_Position = UNI_viewProj * worldPos;\n" + + " mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);\n" + + " vec3 worldNorm = model3 * ATTRIB_normal;\n" + + " varWorldPos = worldPos.xyz;\n" + + " varWorldNormal = worldNorm;\n" + + " varTex0 = ATTRIB_texture0;\n" + + "}\n"; + + VertexShader.Builder sb = new VertexShader.Builder(rs); + sb.addInput(defaultIn); + sb.setObjectConst(objConstBuilder.setX(1).create()); + sb.setShaderConst(shaderConstBuilder.setX(1).create()); + sb.setShader(code); + sSceneManager.mDefaultVertex = sb.create(); + } + + return sSceneManager.mDefaultVertex; + } + + public static FragmentShader getColorFS() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mColor == null) { + RenderScriptGL rs = getRS(); + Element.Builder b = new Element.Builder(rs); + b.add(Element.F32_4(rs), "color"); + Type.Builder objConstBuilder = new Type.Builder(rs, b.create()); + + final String code = "\n" + + "varying vec2 varTex0;\n" + + "void main() {\n" + + " lowp vec4 col = UNI_color;\n" + + " gl_FragColor = col;\n" + + "}\n"; + FragmentShader.Builder fb = new FragmentShader.Builder(rs); + fb.setShader(code); + fb.setObjectConst(objConstBuilder.create()); + sSceneManager.mColor = fb.create(); + } + + return sSceneManager.mColor; + } + + public static FragmentShader getTextureFS() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mTexture == null) { + RenderScriptGL rs = getRS(); + + final String code = "\n" + + "varying vec2 varTex0;\n" + + "void main() {\n" + + " lowp vec4 col = texture2D(UNI_color, varTex0).rgba;\n" + + " gl_FragColor = col;\n" + + "}\n"; + + FragmentShader.Builder fb = new FragmentShader.Builder(rs); + fb.setShader(code); + fb.addTexture(Program.TextureType.TEXTURE_2D, "color"); + sSceneManager.mTexture = fb.create(); + sSceneManager.mTexture.mProgram.bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(rs), 0); + } + + return sSceneManager.mTexture; + } + + static RenderState getDefaultState() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mDefaultState == null) { + sSceneManager.mDefaultState = new RenderState(getDefaultVS(), getColorFS(), null, null); + sSceneManager.mDefaultState.setName("__DefaultState"); + } + return sSceneManager.mDefaultState; + } + + static Transform getDefaultTransform() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.mDefaultTransform == null) { + sSceneManager.mDefaultTransform = new MatrixTransform(); + sSceneManager.mDefaultTransform.setName("__DefaultTransform"); + } + return sSceneManager.mDefaultTransform; + } + + public static SceneManager getInstance() { + if (sSceneManager == null) { + sSceneManager = new SceneManager(); + } + return sSceneManager; + } + + protected SceneManager() { + } + + public void loadModel(String name, SceneLoadedCallback cb) { + ColladaScene scene = new ColladaScene(name, cb); + scene.init(mRS, mRes); + } + + public Mesh getScreenAlignedQuad() { + if (mQuad != null) { + return mQuad; + } + + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, + 3, Mesh.TriangleMeshBuilder.TEXTURE_0); + + tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 1.0f); + tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 1.0f); + tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 1.0f); + tmb.setTexture(1.0f, 1.0f).addVertex(1.0f, 1.0f, 1.0f); + + tmb.addTriangle(0, 1, 2); + tmb.addTriangle(2, 3, 0); + + mQuad = tmb.create(true); + return mQuad; + } + + public Renderable getRenderableQuad(String name, RenderState state) { + Renderable quad = new Renderable(); + quad.setTransform(new MatrixTransform()); + quad.setMesh(getScreenAlignedQuad()); + quad.setName(name); + quad.setRenderState(state); + quad.setCullType(1); + return quad; + } + + public void initRS(RenderScriptGL rs, Resources res, int w, int h) { + mRS = rs; + mRes = res; + mAllocationMap = new HashMap<String, Allocation>(); + + mQuad = null; + mDefault2D = null; + mDefaultCube = null; + mDefaultVertex = null; + mColor = null; + mTexture = null; + mDefaultState = null; + mDefaultTransform = null; + + mExportScript = new ScriptC_export(rs, res, R.raw.export); + + mTransformScript = new ScriptC_transform(rs, res, R.raw.transform); + mTransformScript.set_gTransformScript(mTransformScript); + + mCameraScript = new ScriptC_camera(rs, res, R.raw.camera); + mLightScript = new ScriptC_light(rs, res, R.raw.light); + mObjectParamsScript = new ScriptC_object_params(rs, res, R.raw.object_params); + mFragmentParamsScript = new ScriptC_object_params(rs, res, R.raw.fragment_params); + mVertexParamsScript = new ScriptC_object_params(rs, res, R.raw.vertex_params); + mCullScript = new ScriptC_cull(rs, res, R.raw.cull); + + mRenderLoop = new ScriptC_render(rs, res, R.raw.render); + mRenderLoop.set_gTransformScript(mTransformScript); + mRenderLoop.set_gCameraScript(mCameraScript); + mRenderLoop.set_gLightScript(mLightScript); + mRenderLoop.set_gObjectParamsScript(mObjectParamsScript); + mRenderLoop.set_gFragmentParamsScript(mFragmentParamsScript); + mRenderLoop.set_gVertexParamsScript(mVertexParamsScript); + mRenderLoop.set_gCullScript(mCullScript); + + mRenderLoop.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS)); + } + + public ScriptC getRenderLoop() { + return mRenderLoop; + } +} + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java new file mode 100644 index 0000000..4975114 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; +import java.util.HashMap; + +import com.android.scenegraph.SceneGraphBase; +import com.android.scenegraph.ShaderParam; + +import android.renderscript.*; +import android.renderscript.ProgramFragment.Builder; +import android.util.Log; + +/** + * @hide + */ +public abstract class Shader extends SceneGraphBase { + protected Type mPerObjConstants; + protected Type mPerShaderConstants; + + protected HashMap<String, ShaderParam> mSourceParams; + protected ArrayList<String> mShaderTextureNames; + protected ArrayList<Program.TextureType > mShaderTextureTypes; + protected ArrayList<String> mTextureNames; + protected ArrayList<Program.TextureType > mTextureTypes; + + protected Allocation mConstantBuffer; + protected ScriptField_ShaderParam_s mConstantBufferParams; + + public Shader() { + mSourceParams = new HashMap<String, ShaderParam>(); + mShaderTextureNames = new ArrayList<String>(); + mShaderTextureTypes = new ArrayList<Program.TextureType>(); + mTextureNames = new ArrayList<String>(); + mTextureTypes = new ArrayList<Program.TextureType>(); + } + + public void appendSourceParams(ShaderParam p) { + mSourceParams.put(p.getParamName(), p); + } + + public Type getObjectConstants() { + return mPerObjConstants; + } + + public Type getShaderConstants() { + return mPerObjConstants; + } + + void linkConstants(RenderScriptGL rs) { + if (mPerShaderConstants == null) { + return; + } + + Element constElem = mPerShaderConstants.getElement(); + mConstantBufferParams = ShaderParam.fillInParams(constElem, mSourceParams, null); + + mConstantBuffer = Allocation.createTyped(rs, mPerShaderConstants); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java new file mode 100644 index 0000000..3dd41ca --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; +import java.util.HashMap; + +import com.android.scenegraph.SceneManager; +import com.android.scenegraph.Transform; + +import android.renderscript.Element; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.RenderScriptGL; +import android.util.Log; + +/** + * @hide + */ +public abstract class ShaderParam extends SceneGraphBase { + + static final String cameraPos = "cameraPos"; + static final String cameraDir = "cameraDir"; + + static final String lightColor = "lightColor"; + static final String lightPos = "lightPos"; + static final String lightDir = "lightDir"; + + static final String view = "view"; + static final String proj = "proj"; + static final String viewProj = "viewProj"; + static final String model = "model"; + static final String modelView = "modelView"; + static final String modelViewProj = "modelViewProj"; + + static final long sMaxTimeStamp = 0xffffffffL; + + ScriptField_ShaderParamData_s.Item mData; + ScriptField_ShaderParamData_s mField; + + String mParamName; + Camera mCamera; + + static ScriptField_ShaderParam_s fillInParams(Element constantElem, + HashMap<String, ShaderParam> sourceParams, + Transform transform) { + RenderScriptGL rs = SceneManager.getRS(); + ArrayList<ScriptField_ShaderParam_s.Item> paramList; + paramList = new ArrayList<ScriptField_ShaderParam_s.Item>(); + + int subElemCount = constantElem.getSubElementCount(); + for (int i = 0; i < subElemCount; i ++) { + String inputName = constantElem.getSubElementName(i); + int offset = constantElem.getSubElementOffsetBytes(i); + + ShaderParam matchingParam = sourceParams.get(inputName); + Element subElem = constantElem.getSubElement(i); + // Make one if it's not there + if (matchingParam == null) { + if (subElem.getDataType() == Element.DataType.FLOAT_32) { + matchingParam = new Float4Param(inputName, 0.5f, 0.5f, 0.5f, 0.5f); + } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) { + TransformParam trParam = new TransformParam(inputName); + trParam.setTransform(transform); + matchingParam = trParam; + } + } + ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item(); + paramRS.bufferOffset = offset; + paramRS.transformTimestamp = 0; + paramRS.dataTimestamp = 0; + paramRS.data = matchingParam.getRSData().getAllocation(); + if (subElem.getDataType() == Element.DataType.FLOAT_32) { + paramRS.float_vecSize = subElem.getVectorSize(); + } + + paramList.add(paramRS); + } + + ScriptField_ShaderParam_s rsParams = null; + int paramCount = paramList.size(); + if (paramCount != 0) { + rsParams = new ScriptField_ShaderParam_s(rs, paramCount); + for (int i = 0; i < paramCount; i++) { + rsParams.set(paramList.get(i), i, false); + } + rsParams.copyAll(); + } + return rsParams; + } + + public ShaderParam(String name) { + mParamName = name; + mData = new ScriptField_ShaderParamData_s.Item(); + } + + public String getParamName() { + return mParamName; + } + + public void setCamera(Camera c) { + mCamera = c; + if (mField != null) { + mData.camera = mCamera.getRSData().getAllocation(); + mField.set_camera(0, mData.camera, true); + } + } + + protected void incTimestamp() { + if (mField != null) { + mData.timestamp ++; + mData.timestamp %= sMaxTimeStamp; + mField.set_timestamp(0, mData.timestamp, true); + } + } + + abstract void initLocalData(); + + public ScriptField_ShaderParamData_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + mField = new ScriptField_ShaderParamData_s(rs, 1); + + if (mParamName != null) { + mData.paramName = SceneManager.getCachedAlloc(mParamName); + if (mData.paramName == null) { + mData.paramName = SceneManager.getStringAsAllocation(rs, mParamName); + SceneManager.cacheAlloc(mParamName, mData.paramName); + } + } + initLocalData(); + mData.timestamp = 1; + + mField.set(mData, 0, true); + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java new file mode 100644 index 0000000..b53ab88 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; + +import com.android.scenegraph.SceneManager; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public class Texture2D extends TextureBase { + String mFileName; + String mFileDir; + int mResourceID; + + public Texture2D() { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + } + + public Texture2D(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + setTexture(tex); + } + + public Texture2D(String dir, String file) { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + setFileDir(dir); + setFileName(file); + } + + public Texture2D(int resourceID) { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + mResourceID = resourceID; + } + + public void setFileDir(String dir) { + mFileDir = dir; + } + + public void setFileName(String file) { + mFileName = file; + } + + public String getFileName() { + return mFileName; + } + + public void setTexture(Allocation tex) { + mData.texture = tex != null ? tex : SceneManager.getDefaultTex2D(); + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (mFileName != null && mFileName.length() > 0) { + String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1); + setTexture(SceneManager.loadTexture2D(mFileDir + shortName, rs, res)); + } else if (mResourceID != 0) { + setTexture(SceneManager.loadTexture2D(mResourceID, rs, res)); + } + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + + if (loadNow) { + load(); + } else { + mData.texture = SceneManager.getDefaultTex2D(); + new SingleImageLoaderTask().execute(this); + } + + mField.set(mData, 0, true); + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java new file mode 100644 index 0000000..ba49d4e --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java @@ -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. + */ + +package com.android.scenegraph; + +import java.lang.Math; + +import com.android.scenegraph.SceneManager; +import android.os.AsyncTask; +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public abstract class TextureBase extends SceneGraphBase { + + class SingleImageLoaderTask extends AsyncTask<TextureBase, Void, Boolean> { + protected Boolean doInBackground(TextureBase... objects) { + TextureBase tex = objects[0]; + tex.load(); + return new Boolean(true); + } + protected void onPostExecute(Boolean result) { + } + } + + ScriptField_Texture_s.Item mData; + ScriptField_Texture_s mField; + TextureBase(int type) { + mData = new ScriptField_Texture_s.Item(); + mData.type = type; + } + + protected Allocation mRsTexture; + abstract ScriptField_Texture_s getRsData(boolean loadNow); + abstract void load(); +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java new file mode 100644 index 0000000..1269e3c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; + +import com.android.scenegraph.SceneManager; +import com.android.scenegraph.TextureBase; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public class TextureCube extends TextureBase { + String mFileName; + String mFileDir; + int mResourceID; + + public TextureCube() { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + } + + public TextureCube(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + setTexture(tex); + } + + public TextureCube(String dir, String file) { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + setFileDir(dir); + setFileName(file); + } + + public TextureCube(int resourceID) { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + mResourceID = resourceID; + } + + public void setFileDir(String dir) { + mFileDir = dir; + } + + public void setFileName(String file) { + mFileName = file; + } + + public String getFileName() { + return mFileName; + } + + public void setTexture(Allocation tex) { + mData.texture = tex != null ? tex : SceneManager.getDefaultTexCube(); + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (mFileName != null && mFileName.length() > 0) { + String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1); + setTexture(SceneManager.loadCubemap(mFileDir + shortName, rs, res)); + } else if (mResourceID != 0) { + setTexture(SceneManager.loadCubemap(mResourceID , rs, res)); + } + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + + if (loadNow) { + load(); + } else { + mData.texture = SceneManager.getDefaultTexCube(); + new SingleImageLoaderTask().execute(this); + } + + mField.set(mData, 0, true); + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java new file mode 100644 index 0000000..e656ed2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.graphics.Camera; +import android.renderscript.RenderScriptGL; +import android.renderscript.Float4; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.Element; +import android.util.Log; + +/** + * @hide + */ +public class TextureParam extends ShaderParam { + + TextureBase mTexture; + + public TextureParam(String name) { + super(name); + } + + public TextureParam(String name, TextureBase t) { + super(name); + setTexture(t); + } + + public void setTexture(TextureBase t) { + mTexture = t; + } + + public TextureBase getTexture() { + return mTexture; + } + + void initLocalData() { + mData.type = ScriptC_export.const_ShaderParam_TEXTURE; + if (mTexture != null) { + mData.texture = mTexture.getRsData(false).getAllocation(); + } + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java new file mode 100644 index 0000000..6aa29a5 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java @@ -0,0 +1,69 @@ +/* + * 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.scenegraph; + +import java.lang.Math; + +import com.android.scenegraph.SceneManager; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public class TextureRenderTarget extends TextureBase { + public TextureRenderTarget() { + super(ScriptC_export.const_TextureType_TEXTURE_RENDER_TARGET); + } + + public TextureRenderTarget(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_RENDER_TARGET); + setTexture(tex); + } + + public void setTexture(Allocation tex) { + mData.texture = tex; + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + mField.set(mData, 0, true); + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java new file mode 100644 index 0000000..8180bd0 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.*; +import android.renderscript.Matrix4f; +import android.util.Log; + +/** + * @hide + */ +public abstract class Transform extends SceneGraphBase { + Transform mParent; + ArrayList<Transform> mChildren; + + ScriptField_SgTransform mField; + ScriptField_SgTransform.Item mTransformData; + + public Transform() { + mChildren = new ArrayList<Transform>(); + mParent = null; + } + + public void appendChild(Transform t) { + mChildren.add(t); + t.mParent = this; + updateRSChildData(true); + } + + abstract void initLocalData(); + + void updateRSChildData(boolean copyData) { + if (mField == null) { + return; + } + RenderScriptGL rs = SceneManager.getRS(); + if (mChildren.size() != 0) { + Allocation childRSData = Allocation.createSized(rs, Element.ALLOCATION(rs), + mChildren.size()); + mTransformData.children = childRSData; + + Allocation[] childrenAllocs = new Allocation[mChildren.size()]; + for (int i = 0; i < mChildren.size(); i ++) { + Transform child = mChildren.get(i); + childrenAllocs[i] = child.getRSData().getAllocation(); + } + childRSData.copyFrom(childrenAllocs); + } + if (copyData) { + mField.set(mTransformData, 0, true); + } + } + + ScriptField_SgTransform getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + mField = new ScriptField_SgTransform(rs, 1); + + mTransformData = new ScriptField_SgTransform.Item(); + mTransformData.name = getNameAlloc(rs); + mTransformData.isDirty = 1; + mTransformData.timestamp = 1; + + initLocalData(); + updateRSChildData(false); + + mField.set(mTransformData, 0, true); + return mField; + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java new file mode 100644 index 0000000..d120d5d --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.renderscript.RenderScriptGL; +import android.renderscript.Matrix4f; +import android.renderscript.ProgramFragment; +import android.renderscript.ProgramStore; +import android.renderscript.ProgramVertex; +import android.renderscript.Element; +import android.util.Log; + +/** + * @hide + */ +public class TransformParam extends ShaderParam { + + Transform mTransform; + LightBase mLight; + + public TransformParam(String name) { + super(name); + } + + public void setTransform(Transform t) { + mTransform = t; + if (mField != null && mTransform != null) { + mData.transform = mTransform.getRSData().getAllocation(); + } + incTimestamp(); + } + + int getTypeFromName() { + int paramType = ScriptC_export.const_ShaderParam_TRANSFORM_DATA; + if (mParamName.equalsIgnoreCase(view)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_VIEW; + } else if(mParamName.equalsIgnoreCase(proj)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_PROJ; + } else if(mParamName.equalsIgnoreCase(viewProj)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_VIEW_PROJ; + } else if(mParamName.equalsIgnoreCase(model)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL; + } else if(mParamName.equalsIgnoreCase(modelView)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL_VIEW; + } else if(mParamName.equalsIgnoreCase(modelViewProj)) { + paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL_VIEW_PROJ; + } + return paramType; + } + + void initLocalData() { + mData.type = getTypeFromName(); + if (mTransform != null) { + mData.transform = mTransform.getRSData().getAllocation(); + } + if (mCamera != null) { + mData.camera = mCamera.getRSData().getAllocation(); + } + if (mLight != null) { + mData.light = mLight.getRSData().getAllocation(); + } + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java new file mode 100644 index 0000000..4efaff7 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.scenegraph; + +import java.lang.Math; +import java.util.ArrayList; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public class VertexShader extends Shader { + ProgramVertex mProgram; + ScriptField_VertexShader_s mField; + + public static class Builder { + VertexShader mShader; + ProgramVertex.Builder mBuilder; + + public Builder(RenderScriptGL rs) { + mShader = new VertexShader(); + mBuilder = new ProgramVertex.Builder(rs); + } + + public Builder setShader(Resources resources, int resourceID) { + mBuilder.setShader(resources, resourceID); + return this; + } + + public Builder setShader(String code) { + mBuilder.setShader(code); + return this; + } + + public Builder setObjectConst(Type type) { + mShader.mPerObjConstants = type; + return this; + } + + public Builder setShaderConst(Type type) { + mShader.mPerShaderConstants = type; + return this; + } + + public Builder addInput(Element e) { + mBuilder.addInput(e); + return this; + } + + public VertexShader create() { + if (mShader.mPerShaderConstants != null) { + mBuilder.addConstant(mShader.mPerShaderConstants); + } + if (mShader.mPerObjConstants != null) { + mBuilder.addConstant(mShader.mPerObjConstants); + } + mShader.mProgram = mBuilder.create(); + return mShader; + } + } + + public ProgramVertex getProgram() { + return mProgram; + } + + ScriptField_VertexShader_s getRSData() { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + ScriptField_VertexShader_s.Item item = new ScriptField_VertexShader_s.Item(); + item.program = mProgram; + + linkConstants(rs); + if (mPerShaderConstants != null) { + item.shaderConst = mConstantBuffer; + item.shaderConstParams = mConstantBufferParams.getAllocation(); + mProgram.bindConstants(item.shaderConst, 0); + } + + item.objectConstIndex = -1; + if (mPerObjConstants != null) { + item.objectConstIndex = mPerShaderConstants != null ? 1 : 0; + } + + mField = new ScriptField_VertexShader_s(rs, 1); + mField.set(item, 0, true); + return mField; + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs new file mode 100644 index 0000000..dc0a885 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs @@ -0,0 +1,66 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +//#define DEBUG_CAMERA +#include "scenegraph_objects.rsh" + +void root(const rs_allocation *v_in, rs_allocation *v_out, const float *usrData) { + + SgCamera *cam = (SgCamera *)rsGetElementAt(*v_in, 0); + float aspect = *usrData; + if (cam->aspect != aspect) { + cam->isDirty = 1; + cam->aspect = aspect; + } + if (cam->isDirty) { + rsMatrixLoadPerspective(&cam->proj, cam->horizontalFOV, cam->aspect, cam->near, cam->far); + } + + const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0); + //rsDebug("Camera stamp", cam->transformTimestamp); + //rsDebug("Transform stamp", camTransform->timestamp); + if (camTransform->timestamp != cam->transformTimestamp || cam->isDirty) { + cam->isDirty = 1; + rs_matrix4x4 camPosMatrix; + rsMatrixLoad(&camPosMatrix, &camTransform->globalMat); + float4 zero = {0.0f, 0.0f, 0.0f, 1.0f}; + cam->position = rsMatrixMultiply(&camPosMatrix, zero); + + rsMatrixInverse(&camPosMatrix); + rsMatrixLoad(&cam->view, &camPosMatrix); + + rsMatrixLoad(&cam->viewProj, &cam->proj); + rsMatrixMultiply(&cam->viewProj, &cam->view); + + rsExtractFrustumPlanes(&cam->viewProj, + &cam->frustumPlanes[0], &cam->frustumPlanes[1], + &cam->frustumPlanes[2], &cam->frustumPlanes[3], + &cam->frustumPlanes[3], &cam->frustumPlanes[4]); + } + + if (cam->isDirty) { + cam->timestamp ++; + } + + cam->isDirty = 0; + cam->transformTimestamp = camTransform->timestamp; + +#ifdef DEBUG_CAMERA + printCameraInfo(cam); +#endif //DEBUG_CAMERA +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs new file mode 100644 index 0000000..024e026 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs @@ -0,0 +1,86 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "scenegraph_objects.rsh" + +static void getTransformedSphere(SgRenderable *obj) { + obj->worldBoundingSphere = obj->boundingSphere; + obj->worldBoundingSphere.w = 1.0f; + const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0); + obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere); + + const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f}; + float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec); + scaledVec.w = 0.0f; + obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec); +} + +static bool frustumCulled(SgRenderable *obj, SgCamera *cam) { + if (!obj->bVolInitialized) { + float minX, minY, minZ, maxX, maxY, maxZ; + rsgMeshComputeBoundingBox(obj->mesh, + &minX, &minY, &minZ, + &maxX, &maxY, &maxZ); + //rsDebug("min", minX, minY, minZ); + //rsDebug("max", maxX, maxY, maxZ); + float4 sphere; + sphere.x = (maxX + minX) * 0.5f; + sphere.y = (maxY + minY) * 0.5f; + sphere.z = (maxZ + minZ) * 0.5f; + float3 radius; + radius.x = (maxX - sphere.x); + radius.y = (maxY - sphere.y); + radius.z = (maxZ - sphere.z); + + sphere.w = length(radius); + obj->boundingSphere = sphere; + obj->bVolInitialized = 1; + //rsDebug("Sphere", sphere); + } + + getTransformedSphere(obj); + + return !rsIsSphereInFrustum(&obj->worldBoundingSphere, + &cam->frustumPlanes[0], &cam->frustumPlanes[1], + &cam->frustumPlanes[2], &cam->frustumPlanes[3], + &cam->frustumPlanes[4], &cam->frustumPlanes[5]); +} + + +void root(rs_allocation *v_out, const void *usrData) { + + SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0); + const SgCamera *camera = (const SgCamera*)usrData; + + drawable->isVisible = 0; + // Not loaded yet + if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) { + return; + } + + // check to see if we are culling this object and if it's + // outside the frustum + if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) { +#ifdef DEBUG_RENDERABLES + rsDebug("Culled", drawable); + printName(drawable->name); +#endif // DEBUG_RENDERABLES + return; + } + drawable->isVisible = 1; +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs new file mode 100644 index 0000000..b438a43 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs @@ -0,0 +1,61 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +// The sole purpose of this script is to have various structs exposed +// so that java reflected classes are generated +#include "scenegraph_objects.rsh" + +// Export our native constants to java so that we don't have parallel definitions +const int ShaderParam_FLOAT4_DATA = SHADER_PARAM_FLOAT4_DATA; +const int ShaderParam_TRANSFORM_DATA = SHADER_PARAM_TRANSFORM_DATA; +const int ShaderParam_TRANSFORM_MODEL = SHADER_PARAM_TRANSFORM_MODEL; + +const int ShaderParam_FLOAT4_CAMERA_POS = SHADER_PARAM_FLOAT4_CAMERA_POS; +const int ShaderParam_FLOAT4_CAMERA_DIR = SHADER_PARAM_FLOAT4_CAMERA_DIR; +const int ShaderParam_TRANSFORM_VIEW = SHADER_PARAM_TRANSFORM_VIEW; +const int ShaderParam_TRANSFORM_PROJ = SHADER_PARAM_TRANSFORM_PROJ; +const int ShaderParam_TRANSFORM_VIEW_PROJ = SHADER_PARAM_TRANSFORM_VIEW_PROJ; +const int ShaderParam_TRANSFORM_MODEL_VIEW = SHADER_PARAM_TRANSFORM_MODEL_VIEW; +const int ShaderParam_TRANSFORM_MODEL_VIEW_PROJ = SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ; + +const int ShaderParam_FLOAT4_LIGHT_COLOR = SHADER_PARAM_FLOAT4_LIGHT_COLOR; +const int ShaderParam_FLOAT4_LIGHT_POS = SHADER_PARAM_FLOAT4_LIGHT_POS; +const int ShaderParam_FLOAT4_LIGHT_DIR = SHADER_PARAM_FLOAT4_LIGHT_DIR; + +const int ShaderParam_TEXTURE = SHADER_PARAM_TEXTURE; + +const int Transform_TRANSLATE = TRANSFORM_TRANSLATE; +const int Transform_ROTATE = TRANSFORM_ROTATE; +const int Transform_SCALE = TRANSFORM_SCALE; + +const int TextureType_TEXTURE_2D = TEXTURE_2D; +const int TextureType_TEXTURE_CUBE = TEXTURE_CUBE; +const int TextureType_TEXTURE_RENDER_TARGET = TEXTURE_RENDER_TARGET; + +SgTransform *exportPtr; +SgTransformComponent *componentPtr; +SgRenderState *sExport; +SgRenderable *drExport; +SgRenderPass *pExport; +SgCamera *exportPtrCam; +SgLight *exportPtrLight; +SgShaderParam *spExport; +SgShaderParamData *spDataExport; +SgVertexShader *pvExport; +SgFragmentShader *pfExport; +SgTexture *texExport; diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs new file mode 100644 index 0000000..7202285 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs @@ -0,0 +1,30 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "scenegraph_objects.rsh" + +//#define DEBUG_PARAMS + +#include "params.rsh" + +void root(rs_allocation *v_out, const void *usrData) { + SgFragmentShader *shader = (SgFragmentShader *)rsGetElementAt(*v_out, 0); + const SgCamera *camera = (const SgCamera*)usrData; + processAllParams(shader->shaderConst, shader->shaderConstParams, camera); + processTextureParams(shader); +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs new file mode 100644 index 0000000..e11979f --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs @@ -0,0 +1,33 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +//#define DEBUG_LIGHT +#include "scenegraph_objects.rsh" + +void root(const rs_allocation *v_in, rs_allocation *v_out) { + + SgLight *light = (SgLight *)rsGetElementAt(*v_in, 0); + const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0); + + float4 zero = {0.0f, 0.0f, 0.0f, 1.0f}; + light->position = rsMatrixMultiply(&lTransform->globalMat, zero); + +#ifdef DEBUG_LIGHT + printLightInfo(light); +#endif //DEBUG_LIGHT +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs new file mode 100644 index 0000000..0d524a6 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs @@ -0,0 +1,36 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "scenegraph_objects.rsh" + +//#define DEBUG_PARAMS + +#include "params.rsh" + +void root(rs_allocation *v_out, const void *usrData) { + + SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0); + // Visibility flag was set earlier in the cull stage + if (!drawable->isVisible) { + return; + } + + const SgCamera *camera = (const SgCamera*)usrData; + processAllParams(drawable->pf_const, drawable->pf_constParams, camera); + processAllParams(drawable->pv_const, drawable->pv_constParams, camera); +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh new file mode 100644 index 0000000..575794b --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh @@ -0,0 +1,193 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "scenegraph_objects.rsh" + +//#define DEBUG_PARAMS +static void debugParam(SgShaderParam *p, SgShaderParamData *pData) { + rsDebug("____________ Param ____________", p); + printName(pData->paramName); + rsDebug("bufferOffset", p->bufferOffset); + rsDebug("type ", pData->type); + rsDebug("data timestamp ", pData->timestamp); + rsDebug("param timestamp", p->dataTimestamp); + + const SgTransform *pTransform = NULL; + if (rsIsObject(pData->transform)) { + pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0); + + rsDebug("transform", pTransform); + printName(pTransform->name); + rsDebug("timestamp", pTransform->timestamp); + rsDebug("param timestamp", p->transformTimestamp); + } + + const SgLight *pLight = NULL; + if (rsIsObject(pData->light)) { + pLight = (const SgLight *)rsGetElementAt(pData->light, 0); + printLightInfo(pLight); + } +} + + +static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { +#ifdef DEBUG_PARAMS + rsDebug("Writing value ", *input); + rsDebug("Writing vec size ", vecSize); +#endif // DEBUG_PARAMS + + switch (vecSize) { + case 1: + *ptr = input->x; + break; + case 2: + *((float2*)ptr) = (*input).xy; + break; + case 3: + *((float3*)ptr) = (*input).xyz; + break; + case 4: + *((float4*)ptr) = *input; + break; + } +} + +static bool processParam(SgShaderParam *p, SgShaderParamData *pData, + uint8_t *constantBuffer, + const SgCamera *currentCam, + SgFragmentShader *shader) { + bool isDataOnly = (pData->type > SHADER_PARAM_DATA_ONLY); + const SgTransform *pTransform = NULL; + if (rsIsObject(pData->transform)) { + pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0); + } + + if (isDataOnly) { + // If we are a transform param and our transform is unchanged, nothing to do + if (pTransform) { + if (p->transformTimestamp == pTransform->timestamp) { + return false; + } + p->transformTimestamp = pTransform->timestamp; + } else { + if (p->dataTimestamp == pData->timestamp) { + return false; + } + p->dataTimestamp = pData->timestamp; + } + } + + const SgLight *pLight = NULL; + if (rsIsObject(pData->light)) { + pLight = (const SgLight *)rsGetElementAt(pData->light, 0); + } + + uint8_t *dataPtr = NULL; + const SgTexture *tex = NULL; + if (pData->type == SHADER_PARAM_TEXTURE) { + tex = rsGetElementAt(pData->texture, 0); + } else { + dataPtr = constantBuffer + p->bufferOffset; + } + + switch (pData->type) { + case SHADER_PARAM_TEXTURE: + rsgBindTexture(shader->program, p->bufferOffset, tex->texture); + break; + case SHADER_PARAM_FLOAT4_DATA: + writeFloatData((float*)dataPtr, &pData->float_value, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_POS: + writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_CAMERA_DIR: break; + case SHADER_PARAM_FLOAT4_LIGHT_COLOR: + writeFloatData((float*)dataPtr, &pLight->color, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_LIGHT_POS: + writeFloatData((float*)dataPtr, &pLight->position, p->float_vecSize); + break; + case SHADER_PARAM_FLOAT4_LIGHT_DIR: break; + + case SHADER_PARAM_TRANSFORM_DATA: + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + break; + case SHADER_PARAM_TRANSFORM_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj); + break; + case SHADER_PARAM_TRANSFORM_VIEW_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + break; + case SHADER_PARAM_TRANSFORM_MODEL: + rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ: + rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); + rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, + (rs_matrix4x4*)dataPtr, + &pTransform->globalMat); + break; + } + return true; +} + +static void processAllParams(rs_allocation shaderConst, + rs_allocation allParams, + const SgCamera *camera) { + if (rsIsObject(shaderConst)) { + uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(shaderConst, 0); + + int numParams = 0; + if (rsIsObject(allParams)) { + numParams = rsAllocationGetDimX(allParams); + } + bool updated = false; + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(allParams, i); + SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); +#ifdef DEBUG_PARAMS + debugParam(current, currentData); +#endif // DEBUG_PARAMS + updated = processParam(current, currentData, constantBuffer, camera, NULL) || updated; + } + } +} + +static void processTextureParams(SgFragmentShader *shader) { + int numParams = 0; + if (rsIsObject(shader->shaderTextureParams)) { + numParams = rsAllocationGetDimX(shader->shaderTextureParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(shader->shaderTextureParams, i); + SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); +#ifdef DEBUG_PARAMS + debugParam(current, currentData); +#endif // DEBUG_PARAMS + processParam(current, currentData, NULL, NULL, shader); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs new file mode 100644 index 0000000..8a73dbd --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs @@ -0,0 +1,244 @@ +// Copyright (C) 2011-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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "rs_graphics.rsh" +#include "scenegraph_objects.rsh" + +rs_script gTransformScript; +rs_script gCameraScript; +rs_script gLightScript; +rs_script gObjectParamsScript; +rs_script gFragmentParamsScript; +rs_script gVertexParamsScript; +rs_script gCullScript; + +SgTransform *gRootNode; +rs_allocation gCameras; +rs_allocation gLights; +rs_allocation gFragmentShaders; +rs_allocation gVertexShaders; +rs_allocation gRenderableObjects; + +rs_allocation gRenderPasses; + +// Temporary shaders +rs_program_store gPFSBackground; + +uint32_t *gFrontToBack; +static uint32_t gFrontToBackCount = 0; +uint32_t *gBackToFront; +static uint32_t gBackToFrontCount = 0; + +static SgCamera *gActiveCamera = NULL; + +static rs_allocation nullAlloc; + +// #define DEBUG_RENDERABLES +static void draw(SgRenderable *obj) { +#ifdef DEBUG_RENDERABLES + const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0); + rsDebug("**** Drawing object with transform", obj); + printName(objTransform->name); + rsDebug("Model matrix: ", &objTransform->globalMat); + printName(obj->name); +#endif //DEBUG_RENDERABLES + + const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0); + const SgVertexShader *pv = (const SgVertexShader *)rsGetElementAt(renderState->pv, 0); + const SgFragmentShader *pf = (const SgFragmentShader *)rsGetElementAt(renderState->pf, 0); + + if (pv->objectConstIndex != -1) { + rsgBindConstant(pv->program, pv->objectConstIndex, obj->pv_const); + } + if (pf->objectConstIndex != -1) { + rsgBindConstant(pf->program, pf->objectConstIndex, obj->pf_const); + } + + if (rsIsObject(renderState->ps)) { + rsgBindProgramStore(renderState->ps); + } else { + rsgBindProgramStore(gPFSBackground); + } + + if (rsIsObject(renderState->pr)) { + rsgBindProgramRaster(renderState->pr); + } else { + rs_program_raster pr; + rsgBindProgramRaster(pr); + } + + rsgBindProgramVertex(pv->program); + rsgBindProgramFragment(pf->program); + + for (uint32_t i = 0; i < obj->pf_num_textures; i ++) { + const SgTexture *tex = rsGetElementAt(obj->pf_textures[i], 0); + rsgBindTexture(pf->program, i, tex->texture); + } + + rsgDrawMesh(obj->mesh, obj->meshIndex); +} + +static void sortToBucket(SgRenderable *obj) { + const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0); + if (rsIsObject(renderState->ps)) { + bool isOpaque = false; + if (isOpaque) { + gFrontToBack[gFrontToBackCount++] = (uint32_t)obj; + } else { + gBackToFront[gBackToFrontCount++] = (uint32_t)obj; + } + } else { + gFrontToBack[gFrontToBackCount++] = (uint32_t)obj; + } +} + +static void updateActiveCamera(rs_allocation cam) { + gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0); +} + +static void prepareCameras() { + // now compute all the camera matrices + if (rsIsObject(gCameras)) { + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect)); + } +} + +static void prepareLights() { + if (rsIsObject(gLights)) { + rsForEach(gLightScript, gLights, nullAlloc); + } +} + +static void drawSorted() { + for (int i = 0; i < gFrontToBackCount; i ++) { + SgRenderable *current = (SgRenderable*)gFrontToBack[i]; + draw(current); + } + + for (int i = 0; i < gBackToFrontCount; i ++) { + SgRenderable *current = (SgRenderable*)gBackToFront[i]; + draw(current); + } +} + +static void drawAllObjects(rs_allocation allObj) { + if (!rsIsObject(allObj)) { + return; + } + + if (rsIsObject(gVertexShaders)) { + rsForEach(gVertexParamsScript, nullAlloc, gVertexShaders, + gActiveCamera, sizeof(gActiveCamera)); + } + if (rsIsObject(gFragmentShaders)) { + rsForEach(gFragmentParamsScript, nullAlloc, gFragmentShaders, + gActiveCamera, sizeof(gActiveCamera)); + } + + // Run the params and cull script + rsForEach(gCullScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera)); + rsForEach(gObjectParamsScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera)); + + int numRenderables = rsAllocationGetDimX(allObj); + for (int i = 0; i < numRenderables; i ++) { + rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i); + SgRenderable *current = (SgRenderable*)rsGetElementAt(*drawAlloc, 0); + if (current->isVisible) { + sortToBucket(current); + } + } + drawSorted(); +} + +int root(void) { +#ifdef DEBUG_RENDERABLES + rsDebug("=============================================================================", 0); +#endif // DEBUG_RENDERABLES + + // first step is to update the transform hierachy + if (gRootNode && rsIsObject(gRootNode->children)) { + rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0); + } + + prepareCameras(); + prepareLights(); + + if (rsIsObject(gRenderPasses)) { + rsgClearDepth(1.0f); + int numPasses = rsAllocationGetDimX(gRenderPasses); + for (uint i = 0; i < numPasses; i ++) { + gFrontToBackCount = 0; + gBackToFrontCount = 0; + SgRenderPass *pass = (SgRenderPass*)rsGetElementAt(gRenderPasses, i); + if (rsIsObject(pass->color_target)) { + rsgBindColorTarget(pass->color_target, 0); + } + if (rsIsObject(pass->depth_target)) { + rsgBindDepthTarget(pass->depth_target); + } + if (!rsIsObject(pass->color_target) && + !rsIsObject(pass->depth_target)) { + rsgClearAllRenderTargets(); + } + updateActiveCamera(pass->camera); + if (pass->should_clear_color) { + rsgClearColor(pass->clear_color.x, pass->clear_color.y, + pass->clear_color.z, pass->clear_color.w); + } + if (pass->should_clear_depth) { + rsgClearDepth(pass->clear_depth); + } + drawAllObjects(pass->objects); + } + } else { + gFrontToBackCount = 0; + gBackToFrontCount = 0; + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + + if (rsIsObject(gCameras)) { + rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 0); + updateActiveCamera(*camAlloc); + } + drawAllObjects(gRenderableObjects); + } + return 10; +} + +// Search through sorted and culled objects +void pick(int screenX, int screenY) { + float3 pnt, vec; + getCameraRay(gActiveCamera, screenX, screenY, &pnt, &vec); + + for (int i = 0; i < gFrontToBackCount; i ++) { + SgRenderable *current = (SgRenderable*)gFrontToBack[i]; + bool isPicked = intersect(current, pnt, vec); + if (isPicked) { + current->cullType = CULL_ALWAYS; + } + } + + for (int i = 0; i < gBackToFrontCount; i ++) { + SgRenderable *current = (SgRenderable*)gBackToFront[i]; + bool isPicked = intersect(current, pnt, vec); + if (isPicked) { + current->cullType = CULL_ALWAYS; + } + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh new file mode 100644 index 0000000..bdca3ab --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh @@ -0,0 +1,323 @@ +// Copyright (C) 2011-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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#ifndef _TRANSFORM_DEF_ +#define _TRANSFORM_DEF_ + +#include "rs_graphics.rsh" + +#define TRANSFORM_NONE 0 +#define TRANSFORM_TRANSLATE 1 +#define TRANSFORM_ROTATE 2 +#define TRANSFORM_SCALE 3 + +#define CULL_FRUSTUM 0 +#define CULL_ALWAYS 2 + +#define LIGHT_POINT 0 +#define LIGHT_DIRECTIONAL 1 + +// Shader params that involve only data +#define SHADER_PARAM_DATA_ONLY 10000 +#define SHADER_PARAM_FLOAT4_DATA 10001 +#define SHADER_PARAM_TRANSFORM_DATA 10002 +#define SHADER_PARAM_TRANSFORM_MODEL 10003 + +// Shader params that involve camera +#define SHADER_PARAM_CAMERA 1000 +#define SHADER_PARAM_FLOAT4_CAMERA_POS 1001 +#define SHADER_PARAM_FLOAT4_CAMERA_DIR 1002 +#define SHADER_PARAM_TRANSFORM_VIEW 1003 +#define SHADER_PARAM_TRANSFORM_PROJ 1004 +#define SHADER_PARAM_TRANSFORM_VIEW_PROJ 1005 +#define SHADER_PARAM_TRANSFORM_MODEL_VIEW 1006 +#define SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ 1007 + +// Shader Params that only involve lights +#define SHADER_PARAM_LIGHT 100 +#define SHADER_PARAM_FLOAT4_LIGHT_COLOR 103 +#define SHADER_PARAM_FLOAT4_LIGHT_POS 104 +#define SHADER_PARAM_FLOAT4_LIGHT_DIR 105 + +#define SHADER_PARAM_TEXTURE 10 + +#define TEXTURE_NONE 0 +#define TEXTURE_2D 1 +#define TEXTURE_CUBE 2 +#define TEXTURE_RENDER_TARGET 3 + +typedef struct TransformComponent_s { + float4 value; + int type; + rs_allocation name; +} SgTransformComponent; + +typedef struct __attribute__((packed, aligned(4))) SgTransform { + rs_matrix4x4 globalMat; + rs_matrix4x4 localMat; + + rs_allocation components; + int isDirty; + + rs_allocation children; + rs_allocation name; + + // Used to check whether transform params need to be updated + uint32_t timestamp; +} SgTransform; + +typedef struct VertexShader_s { + rs_program_vertex program; + // Buffer with vertex constant data + rs_allocation shaderConst; + // ShaderParam's that populate data + rs_allocation shaderConstParams; + // location of the per object constants on the buffer + int objectConstIndex; +} SgVertexShader; + +typedef struct FragmentShader_s { + rs_program_fragment program; + // Buffer with vertex constant data + rs_allocation shaderConst; + // ShaderParam's that populate data + rs_allocation shaderConstParams; + // ShaderParam's that set textures + rs_allocation shaderTextureParams; + // location of the per object constants on the buffer + int objectConstIndex; +} SgFragmentShader; + +typedef struct RenderState_s { + rs_allocation pv; // VertexShader struct + rs_allocation pf; // FragmentShader struct + rs_program_store ps; + rs_program_raster pr; +} SgRenderState; + +typedef struct Renderable_s { + rs_allocation render_state; + // Buffer with vertex constant data + rs_allocation pv_const; + // ShaderParam's that populate data + rs_allocation pv_constParams; + // Buffer with fragment constant data + rs_allocation pf_const; + // ShaderParam's that populate data + rs_allocation pf_constParams; + rs_allocation pf_textures[8]; + int pf_num_textures; + rs_mesh mesh; + int meshIndex; + rs_allocation transformMatrix; + rs_allocation name; + float4 boundingSphere; + float4 worldBoundingSphere; + int bVolInitialized; + int cullType; // specifies whether to frustum cull + int isVisible; +} SgRenderable; + +typedef struct RenderPass_s { + rs_allocation color_target; + rs_allocation depth_target; + rs_allocation camera; + rs_allocation objects; + + float4 clear_color; + float clear_depth; + bool should_clear_color; + bool should_clear_depth; +} SgRenderPass; + +typedef struct Camera_s { + rs_matrix4x4 proj; + rs_matrix4x4 view; + rs_matrix4x4 viewProj; + float4 position; + float near; + float far; + float horizontalFOV; + float aspect; + rs_allocation name; + rs_allocation transformMatrix; + float4 frustumPlanes[6]; + + int isDirty; + // Timestamp of the camera itself to signal params if anything changes + uint32_t timestamp; + // Timestamp of our transform + uint32_t transformTimestamp; +} SgCamera; + +typedef struct Light_s { + float4 position; + float4 color; + float intensity; + int type; + rs_allocation name; + rs_allocation transformMatrix; +} SgLight; + +// This represents the shader parameter data needed to set a float or transform data +typedef struct ShaderParamData_s { + int type; + float4 float_value; + uint32_t timestamp; + rs_allocation paramName; + rs_allocation camera; + rs_allocation light; + rs_allocation transform; + rs_allocation texture; +} SgShaderParamData; + +// This represents a shader parameter that knows how to update itself for a given +// renderable or shader and contains a timestamp for the last time this buffer was updated +typedef struct ShaderParam_s { + // Used to check whether transform params need to be updated + uint32_t transformTimestamp; + // Used to check whether data params need to be updated + // These are used when somebody set the matrix of float value directly in java + uint32_t dataTimestamp; + // Specifies where in the constant buffer data gets written to + int bufferOffset; + // An instance of SgShaderParamData that could be shared by multiple objects + rs_allocation data; + // How many components of the vector we need to write + int float_vecSize; +} SgShaderParam; + +// This represents a texture object +typedef struct Texture_s { + uint32_t type; + rs_allocation texture; +} SgTexture; + +static void printName(rs_allocation name) { + if (!rsIsObject(name)) { + rsDebug("no name", 0); + return; + } + + rsDebug((const char*)rsGetElementAt(name, 0), 0); +} + +static void printCameraInfo(const SgCamera *cam) { + rsDebug("***** Camera information. ptr:", cam); + printName(cam->name); + const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0); + rsDebug("Transform name:", camTransform); + printName(camTransform->name); + + rsDebug("Aspect: ", cam->aspect); + rsDebug("Near: ", cam->near); + rsDebug("Far: ", cam->far); + rsDebug("Fov: ", cam->horizontalFOV); + rsDebug("Position: ", cam->position); + rsDebug("Proj: ", &cam->proj); + rsDebug("View: ", &cam->view); +} + +static void printLightInfo(const SgLight *light) { + rsDebug("***** Light information. ptr:", light); + printName(light->name); + const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0); + rsDebug("Transform name:", lTransform); + printName(lTransform->name); + + rsDebug("Position: ", light->position); + rsDebug("Color : ", light->color); + rsDebug("Intensity: ", light->intensity); + rsDebug("Type: ", light->type); +} + +static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) { + rsDebug("=================================", screenX); + rsDebug("Point X", screenX); + rsDebug("Point Y", screenY); + + rs_matrix4x4 mvpInv; + rsMatrixLoad(&mvpInv, &cam->viewProj); + rsMatrixInverse(&mvpInv); + + float width = (float)rsgGetWidth(); + float height = (float)rsgGetHeight(); + + float4 pos = {(float)screenX, height - (float)screenY, 0.0f, 1.0f}; + + pos.x /= width; + pos.y /= height; + + rsDebug("Pre Norm X", pos.x); + rsDebug("Pre Norm Y", pos.y); + + pos.xy = pos.xy * 2.0f - 1.0f; + + rsDebug("Norm X", pos.x); + rsDebug("Norm Y", pos.y); + + pos = rsMatrixMultiply(&mvpInv, pos); + float oneOverW = 1.0f / pos.w; + pos.xyz *= oneOverW; + + rsDebug("World X", pos.x); + rsDebug("World Y", pos.y); + rsDebug("World Z", pos.z); + + rsDebug("Cam X", cam->position.x); + rsDebug("Cam Y", cam->position.y); + rsDebug("Cam Z", cam->position.z); + + *vec = normalize(pos.xyz - cam->position.xyz); + rsDebug("Vec X", vec->x); + rsDebug("Vec Y", vec->y); + rsDebug("Vec Z", vec->z); + *pnt = cam->position.xyz; +} + +static bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) { + // Solving for t^2 + Bt + C = 0 + float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz; + float B = dot(originMinusCenter, vec) * 2.0f; + float C = dot(originMinusCenter, originMinusCenter) - + obj->worldBoundingSphere.w * obj->worldBoundingSphere.w; + + float discriminant = B * B - 4.0f * C; + if (discriminant < 0.0f) { + return false; + } + discriminant = sqrt(discriminant); + + float t0 = (-B - discriminant) * 0.5f; + float t1 = (-B + discriminant) * 0.5f; + + if (t0 > t1) { + float temp = t0; + t0 = t1; + t1 = temp; + } + + // The sphere is behind us + if (t1 < 0.0f) { + return false; + } + return true; +} + + +#endif // _TRANSFORM_DEF_ diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs new file mode 100644 index 0000000..941b5a8 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs @@ -0,0 +1,127 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.modelviewer) + +#include "scenegraph_objects.rsh" + +rs_script gTransformScript; + +typedef struct { + int changed; + rs_matrix4x4 *mat; +} ParentData; + +//#define DEBUG_TRANSFORMS +static void debugTransform(SgTransform *data, const ParentData *parent) { + rsDebug("****** <Transform> ******", (int)data); + printName(data->name); + rsDebug("isDirty", data->isDirty); + rsDebug("parent", (int)parent); + rsDebug("child ", rsIsObject(data->children)); + + // Refresh matrices if dirty + if (data->isDirty && rsIsObject(data->components)) { + uint32_t numComponenets = rsAllocationGetDimX(data->components); + for (int i = 0; i < numComponenets; i ++) { + const SgTransformComponent *comp = NULL; + comp = (const SgTransformComponent *)rsGetElementAt(data->components, i); + + if (rsIsObject(comp->name)) { + rsDebug((const char*)rsGetElementAt(comp->name, 0), comp->value); + rsDebug("Type", comp->type); + } else { + rsDebug("no name", comp->value); + rsDebug("Type", comp->type); + } + } + } + + rsDebug("timestamp", data->timestamp); + rsDebug("****** </Transform> ******", (int)data); +} + +static void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) { + rs_matrix4x4 temp; + + switch (type) { + case TRANSFORM_TRANSLATE: + rsMatrixLoadTranslate(&temp, data.x, data.y, data.z); + break; + case TRANSFORM_ROTATE: + rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z); + break; + case TRANSFORM_SCALE: + rsMatrixLoadScale(&temp, data.x, data.y, data.z); + break; + } + rsMatrixMultiply(mat, &temp); +} + +void root(const rs_allocation *v_in, rs_allocation *v_out, const void *usrData) { + + SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0); + const ParentData *parent = (const ParentData *)usrData; + +#ifdef DEBUG_TRANSFORMS + debugTransform(data, parent); +#endif //DEBUG_TRANSFORMS + + rs_matrix4x4 *localMat = &data->localMat; + rs_matrix4x4 *globalMat = &data->globalMat; + + // Refresh matrices if dirty + if (data->isDirty && rsIsObject(data->components)) { + bool resetLocal = false; + uint32_t numComponenets = rsAllocationGetDimX(data->components); + for (int i = 0; i < numComponenets; i ++) { + if (!resetLocal) { + // Reset our local matrix only for component transforms + rsMatrixLoadIdentity(localMat); + resetLocal = true; + } + const SgTransformComponent *comp = NULL; + comp = (const SgTransformComponent *)rsGetElementAt(data->components, i); + appendTransformation(comp->type, comp->value, localMat); + } + } + + if (parent) { + data->isDirty = (parent->changed || data->isDirty) ? 1 : 0; + if (data->isDirty) { + rsMatrixLoad(globalMat, parent->mat); + rsMatrixMultiply(globalMat, localMat); + } + } else if (data->isDirty) { + rsMatrixLoad(globalMat, localMat); + } + + ParentData toChild; + toChild.changed = 0; + toChild.mat = globalMat; + + if (data->isDirty) { + toChild.changed = 1; + data->timestamp ++; + } + + if (rsIsObject(data->children)) { + rs_allocation nullAlloc; + rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild)); + } + + data->isDirty = 0; +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs new file mode 100644 index 0000000..88955a8 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs @@ -0,0 +1,29 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.scenegraph) + +#include "scenegraph_objects.rsh" + +//#define DEBUG_PARAMS + +#include "params.rsh" + +void root(rs_allocation *v_out, const void *usrData) { + SgVertexShader *shader = (SgVertexShader *)rsGetElementAt(*v_out, 0); + const SgCamera *camera = (const SgCamera*)usrData; + processAllParams(shader->shaderConst, shader->shaderConstParams, camera); +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java new file mode 100644 index 0000000..420e133 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.List; + +import android.app.ListActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +/** + * A list view where the last item the user clicked is placed in + * the "activated" state, causing its background to highlight. + */ +public class FileSelector extends ListActivity { + + File[] mCurrentSubList; + File mCurrentFile; + + class DAEFilter implements FileFilter { + public boolean accept(File file) { + if (file.isDirectory()) { + return true; + } + return file.getName().endsWith(".dae"); + } + } + + private void populateList(File file) { + + mCurrentFile = file; + setTitle(mCurrentFile.getAbsolutePath() + "/*.dae"); + List<String> names = new ArrayList<String>(); + names.add(".."); + + mCurrentSubList = mCurrentFile.listFiles(new DAEFilter()); + + if (mCurrentSubList != null) { + for (int i = 0; i < mCurrentSubList.length; i ++) { + String fileName = mCurrentSubList[i].getName(); + if (mCurrentSubList[i].isDirectory()) { + fileName = "/" + fileName; + } + names.add(fileName); + } + } + + // Use the built-in layout for showing a list item with a single + // line of text whose background is changes when activated. + setListAdapter(new ArrayAdapter<String>(this, + android.R.layout.simple_list_item_activated_1, names)); + getListView().setTextFilterEnabled(true); + + // Tell the list view to show one checked/activated item at a time. + getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + populateList(new File("/sdcard/")); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + if (position == 0) { + File parent = mCurrentFile.getParentFile(); + if (parent == null) { + return; + } + populateList(parent); + return; + } + + // the first thing in list is parent directory + File selectedFile = mCurrentSubList[position - 1]; + if (selectedFile.isDirectory()) { + populateList(selectedFile); + return; + } + + Intent resultIntent = new Intent(); + resultIntent.setData(Uri.fromFile(selectedFile)); + setResult(RESULT_OK, resultIntent); + finish(); + } + +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java new file mode 100644 index 0000000..28f916c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java @@ -0,0 +1,192 @@ +/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.testapp;
+
+import java.util.ArrayList;
+
+import com.android.scenegraph.*;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+class FullscreenBlur {
+
+ static TextureRenderTarget sRenderTargetBlur0Color;
+ static TextureRenderTarget sRenderTargetBlur0Depth;
+ static TextureRenderTarget sRenderTargetBlur1Color;
+ static TextureRenderTarget sRenderTargetBlur1Depth;
+ static TextureRenderTarget sRenderTargetBlur2Color;
+ static TextureRenderTarget sRenderTargetBlur2Depth;
+
+ static FragmentShader mPF_BlurH;
+ static FragmentShader mPF_BlurV;
+ static FragmentShader mPF_SelectColor;
+ static FragmentShader mPF_Texture;
+ static VertexShader mPV_Paint;
+ static VertexShader mPV_Blur;
+
+ static int targetWidth;
+ static int targetHeight;
+
+ // This is only used when full screen blur is enabled
+ // Basically, it's the offscreen render targets
+ static void createRenderTargets(RenderScriptGL rs, int w, int h) {
+ targetWidth = w/8;
+ targetHeight = h/8;
+ Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
+ Type renderType = b.setX(targetWidth).setY(targetHeight).create();
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur1Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur2Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+
+ b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ renderType = b.setX(targetWidth).setY(targetHeight).create();
+ usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur1Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur2Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ }
+
+ static void addOffsets(Renderable quad, float advance) {
+ quad.appendSourceParams(new Float4Param("blurOffset0", - advance * 2.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset1", - advance * 0.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset2", advance * 1.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset3", advance * 3.5f));
+ }
+
+ static RenderPass addPass(Scene scene, Camera cam, TextureRenderTarget color, TextureRenderTarget depth) {
+ RenderPass pass = new RenderPass();
+ pass.setColorTarget(color);
+ pass.setDepthTarget(depth);
+ pass.setShouldClearColor(false);
+ pass.setShouldClearDepth(false);
+ pass.setCamera(cam);
+ scene.appendRenderPass(pass);
+ return pass;
+ }
+
+ static void addBlurPasses(Scene scene, RenderScriptGL rs, Camera cam) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ ArrayList<RenderableBase> allDraw = scene.getRenderables();
+ int numDraw = allDraw.size();
+
+ ProgramRaster cullNone = ProgramRaster.CULL_NONE(rs);
+ ProgramStore blendAdd = SceneManager.BLEND_ADD_DEPTH_NONE(rs);
+ ProgramStore blendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(rs);
+
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture, blendAdd, cullNone);
+ RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor, blendNone, cullNone);
+ RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH, blendNone, cullNone);
+ RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV, blendNone, cullNone);
+
+ // Renders the scene off screen
+ RenderPass blurSourcePass = addPass(scene, cam,
+ sRenderTargetBlur0Color,
+ sRenderTargetBlur0Depth);
+ blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ blurSourcePass.setShouldClearColor(true);
+ blurSourcePass.setClearDepth(1.0f);
+ blurSourcePass.setShouldClearDepth(true);
+ for (int i = 0; i < numDraw; i ++) {
+ blurSourcePass.appendRenderable((Renderable)allDraw.get(i));
+ }
+
+ // Pass for selecting bright colors
+ RenderPass selectColorPass = addPass(scene, cam,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur0Color));
+ selectColorPass.appendRenderable(quad);
+
+ // Horizontal blur
+ RenderPass horizontalBlurPass = addPass(scene, cam,
+ sRenderTargetBlur1Color,
+ sRenderTargetBlur1Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur2Color));
+ addOffsets(quad, 1.0f / (float)targetWidth);
+ horizontalBlurPass.appendRenderable(quad);
+
+ // Vertical Blur
+ RenderPass verticalBlurPass = addPass(scene, cam,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur1Color));
+ addOffsets(quad, 1.0f / (float)targetHeight);
+ verticalBlurPass.appendRenderable(quad);
+ }
+
+ // Additively renders the blurred colors on top of the scene
+ static void addCompositePass(Scene scene, RenderScriptGL rs, Camera cam) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ SceneManager.BLEND_ADD_DEPTH_NONE(rs),
+ ProgramRaster.CULL_NONE(rs));
+
+ RenderPass compositePass = addPass(scene, cam, null, null);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadComposite", drawTex);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur2Color));
+ compositePass.appendRenderable(quad);
+ }
+
+ static private FragmentShader getShader(Resources res, RenderScriptGL rs,
+ int resID, Type constants) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(rs);
+ fb.setShader(res, resID);
+ fb.addTexture(TextureType.TEXTURE_2D, "color");
+ if (constants != null) {
+ fb.setObjectConst(constants);
+ }
+ FragmentShader prog = fb.create();
+ prog.getProgram().bindSampler(Sampler.CLAMP_LINEAR(rs), 0);
+ return prog;
+ }
+
+ static void initShaders(Resources res, RenderScriptGL rs) {
+ ScriptField_BlurOffsets blurConst = new ScriptField_BlurOffsets(rs, 1);
+ VertexShader.Builder vb = new VertexShader.Builder(rs);
+ vb.addInput(ScriptField_VertexShaderInputs.createElement(rs));
+ vb.setShader(res, R.raw.blur_vertex);
+ mPV_Blur = vb.create();
+
+ mPF_Texture = getShader(res, rs, R.raw.texture, null);
+ mPF_Texture.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(rs), 0);
+ mPF_BlurH = getShader(res, rs, R.raw.blur_h, blurConst.getAllocation().getType());
+ mPF_BlurV = getShader(res, rs, R.raw.blur_v, blurConst.getAllocation().getType());
+ mPF_SelectColor = getShader(res, rs, R.raw.select_color, null);
+ }
+
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleApp.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleApp.java new file mode 100644 index 0000000..314db80 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleApp.java @@ -0,0 +1,46 @@ +/* + * 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.testapp; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.Window; +import android.view.Window; +import android.net.Uri; + +import java.lang.Runtime; + +public class SimpleApp extends Activity { + + private SimpleAppView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new SimpleAppView(this); + setContentView(mView); + } +} + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java new file mode 100644 index 0000000..fff6f34 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java @@ -0,0 +1,207 @@ +/* + * 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.testapp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import com.android.scenegraph.*; +import com.android.scenegraph.SceneManager.SceneLoadedCallback; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Program.TextureType; +import android.util.Log; + +// This is where the scenegraph and the rendered objects are initialized and used +public class SimpleAppRS { + SceneManager mSceneManager; + + RenderScriptGL mRS; + Resources mRes; + + Scene mScene; + Mesh mSimpleMesh; + Mesh mSphereMesh; + Mesh mCubeMesh; + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mSceneManager = SceneManager.getInstance(); + mSceneManager.initRS(mRS, mRes, width, height); + + mScene = new Scene(); + + setupGeometry(); + setupColoredQuad(); + setupTexturedQuad(); + setupShadedGeometry(); + setupCamera(); + setupRenderPass(); + + mSceneManager.setActiveScene(mScene); + + mScene.initRS(); + mRS.bindRootScript(mSceneManager.getRenderLoop()); + } + + private void setupGeometry() { + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, 3, + Mesh.TriangleMeshBuilder.TEXTURE_0); + + // Create four vertices with texture coordinates + tmb.setTexture(0.0f, 1.0f).addVertex(-1.0f, 1.0f, 0.0f); + tmb.setTexture(0.0f, 0.0f).addVertex(-1.0f, -1.0f, 0.0f); + tmb.setTexture(1.0f, 0.0f).addVertex(1.0f, -1.0f, 0.0f); + tmb.setTexture(1.0f, 1.0f).addVertex(1.0f, 1.0f, 0.0f); + + tmb.addTriangle(0, 1, 2); + tmb.addTriangle(2, 3, 0); + mSimpleMesh = tmb.create(true); + + // Load a file that constains two pieces of geometry, a sphere and a cube + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.unit_obj); + for (int i = 0; i < model.getIndexEntryCount(); i ++) { + FileA3D.IndexEntry entry = model.getIndexEntry(i); + if (entry != null && entry.getName().equals("CubeMesh")) { + mCubeMesh = entry.getMesh(); + } else if (entry != null && entry.getName().equals("SphereMesh")) { + mSphereMesh = entry.getMesh(); + } + } + } + + private void setupColoredQuad() { + // Built-in shader that provides position, texcoord and normal + VertexShader genericV = SceneManager.getDefaultVS(); + // Built-in shader that displays a color + FragmentShader colorF = SceneManager.getColorFS(); + RenderState colorRS = new RenderState(genericV, colorF, null, null); + + // Draw a simple colored quad + Renderable quad = mScene.appendNewRenderable(); + quad.setMesh(mSimpleMesh); + // Our shader has a constant input called "color" + // This tells the scenegraph to assign the following float3 to that input + quad.appendSourceParams(new Float4Param("color", 0.2f, 0.3f, 0.4f)); + quad.setRenderState(colorRS); + } + + private void setupTexturedQuad() { + // Built-in shader that provides position, texcoord and normal + VertexShader genericV = SceneManager.getDefaultVS(); + // Built-in shader that displays a texture + FragmentShader textureF = SceneManager.getTextureFS(); + // We want to use transparency based on the alpha channel of the texture + ProgramStore alphaBlend = ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS); + RenderState texRS = new RenderState(genericV, textureF, alphaBlend, null); + + // Draw a textured quad + Renderable quad = mScene.appendNewRenderable(); + quad.setMesh(mSimpleMesh); + // Make a transform to position the quad + CompoundTransform t = mScene.appendNewCompoundTransform(); + t.addTranslate("position", new Float3(2, 2, 0)); + quad.setTransform(t); + // Our fragment shader has a constant texture input called "color" + // This will assign an icon from drawables to that input + quad.appendSourceParams(new TextureParam("color", new Texture2D(R.drawable.icon))); + quad.setRenderState(texRS); + } + + private FragmentShader createLambertShader() { + // Describe what constant inputs our shader wants + Element.Builder b = new Element.Builder(mRS); + b.add(Element.F32_4(mRS), "cameraPos"); + + // Create a shader from a text file in resources + FragmentShader.Builder fb = new FragmentShader.Builder(mRS); + // Tell the shader what constants we want + fb.setShaderConst(new Type.Builder(mRS, b.create()).setX(1).create()); + // Shader code location + fb.setShader(mRes, R.raw.diffuse); + // We want a texture called diffuse on our shader + fb.addTexture(TextureType.TEXTURE_2D, "diffuse"); + FragmentShader shader = fb.create(); + mScene.appendShader(shader); + return shader; + } + + private void setupShadedGeometry() { + // Built-in shader that provides position, texcoord and normal + VertexShader genericV = SceneManager.getDefaultVS(); + // Custom shader + FragmentShader diffuseF = createLambertShader(); + RenderState diffuseRS = new RenderState(genericV, diffuseF, null, null); + + // Draw a sphere + Renderable sphere = mScene.appendNewRenderable(); + // Use the sphere geometry loaded earlier + sphere.setMesh(mSphereMesh); + // Make a transform to position the sphere + CompoundTransform t = mScene.appendNewCompoundTransform(); + t.addTranslate("position", new Float3(-1, 2, 3)); + t.addScale("scale", new Float3(1.4f, 1.4f, 1.4f)); + sphere.setTransform(t); + // Tell the renderable which texture to use when we draw + // This will mean a texture param in the shader called "diffuse" + // will be assigned a texture called red.jpg + sphere.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "red.jpg"))); + sphere.setRenderState(diffuseRS); + + // Draw a cube + Renderable cube = mScene.appendNewRenderable(); + cube.setMesh(mCubeMesh); + t = mScene.appendNewCompoundTransform(); + t.addTranslate("position", new Float3(-2, -2.1f, 0)); + t.addRotate("rotateX", new Float3(1, 0, 0), 30); + t.addRotate("rotateY", new Float3(0, 1, 0), 30); + t.addScale("scale", new Float3(2, 2, 2)); + cube.setTransform(t); + cube.appendSourceParams(new TextureParam("diffuse", new Texture2D("", "orange.jpg"))); + cube.setRenderState(diffuseRS); + } + + private void setupCamera() { + Camera camera = mScene.appendNewCamera(); + camera.setFar(200); + camera.setNear(0.1f); + camera.setFOV(60); + CompoundTransform cameraTransform = mScene.appendNewCompoundTransform(); + cameraTransform.addTranslate("camera", new Float3(0, 0, 10)); + camera.setTransform(cameraTransform); + } + + private void setupRenderPass() { + RenderPass mainPass = mScene.appendNewRenderPass(); + mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f)); + mainPass.setShouldClearColor(true); + mainPass.setClearDepth(1.0f); + mainPass.setShouldClearDepth(true); + mainPass.setCamera(mScene.getCameras().get(0)); + ArrayList<RenderableBase> allRender = mScene.getRenderables(); + for (RenderableBase renderable : allRender) { + mainPass.appendRenderable((Renderable)renderable); + } + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppView.java new file mode 100644 index 0000000..2112181 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppView.java @@ -0,0 +1,62 @@ +/* + * 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.testapp; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +public class SimpleAppView extends RSSurfaceView { + + public SimpleAppView(Context context) { + super(context); + } + + private RenderScriptGL mRS; + SimpleAppRS mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + sc.setSamples(1, 2, 1); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new SimpleAppRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRender = null; + mRS = null; + destroyRenderScriptGL(); + } + } +} + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java new file mode 100644 index 0000000..385a7ab --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; +import android.view.MenuInflater; +import android.view.Window; +import android.net.Uri; + +import java.lang.Runtime; + +public class TestApp extends Activity { + + private TestAppView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new TestAppView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.pause(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.loader_menu, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.load_model: + loadModel(); + return true; + case R.id.use_blur: + mView.mRender.toggleBlur(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private static final int FIND_DAE_MODEL = 10; + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (resultCode == RESULT_OK) { + if (requestCode == FIND_DAE_MODEL) { + Uri selectedImageUri = data.getData(); + Log.e("Selected Path: ", selectedImageUri.getPath()); + mView.mRender.loadModel(selectedImageUri.getPath()); + } + } + } + + public void loadModel() { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_PICK); + intent.setClassName("com.android.testapp", + "com.android.testapp.FileSelector"); + startActivityForResult(intent, FIND_DAE_MODEL); + } + +} + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java new file mode 100644 index 0000000..5bd8f0b --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java @@ -0,0 +1,113 @@ +/* + * 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.testapp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import com.android.scenegraph.SceneManager; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Allocation.MipmapControl; +import android.renderscript.Element.Builder; +import android.renderscript.Font.Style; +import android.renderscript.Program.TextureType; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + +// This is where the scenegraph and the rendered objects are initialized and used +public class TestAppLoadingScreen { + + private static String TAG = "TestAppLoadingScreen"; + + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_test_app mScript; + + public TestAppLoadingScreen(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + // Shows the loading screen with some text + renderLoading(); + // Adds a little 3D bugdroid model to the laoding screen asynchronously. + new LoadingScreenLoaderTask().execute(); + } + + public void showLoadingScreen(boolean show) { + if (show) { + mRS.bindRootScript(mScript); + } else { + mRS.bindRootScript(SceneManager.getInstance().getRenderLoop()); + } + } + + // The loading screen has some elements that shouldn't be loaded on the UI thread + private class LoadingScreenLoaderTask extends AsyncTask<String, Void, Boolean> { + Allocation robotTex; + Mesh robotMesh; + protected Boolean doInBackground(String... names) { + long start = System.currentTimeMillis(); + robotTex = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot, + MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE, + Allocation.USAGE_GRAPHICS_TEXTURE); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) { + robotMesh = entry.getMesh(); + } + + mScript.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS)); + + ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS); + b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + ProgramFragment pfDefault = b.create(); + pfDefault.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0); + mScript.set_gPFBackground(pfDefault); + + ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS); + ProgramVertexFixedFunction pvDefault = pvb.create(); + ProgramVertexFixedFunction.Constants va = new ProgramVertexFixedFunction.Constants(mRS); + ((ProgramVertexFixedFunction)pvDefault).bindConstants(va); + mScript.set_gPVBackground(pvDefault); + + long end = System.currentTimeMillis(); + Log.v("TIMER", "Loading load time: " + (end - start)); + return new Boolean(true); + } + + protected void onPostExecute(Boolean result) { + mScript.set_gRobotTex(robotTex); + mScript.set_gRobotMesh(robotMesh); + } + } + + // Creates a simple script to show a loding screen until everything is initialized + // Could also be used to do some custom renderscript work before handing things over + // to the scenegraph + void renderLoading() { + mScript = new ScriptC_test_app(mRS, mRes, R.raw.test_app); + mRS.bindRootScript(mScript); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java new file mode 100644 index 0000000..3aa80f4 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2011-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.testapp; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import com.android.scenegraph.*; +import com.android.scenegraph.SceneManager.SceneLoadedCallback; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.AsyncTask; +import android.renderscript.*; +import android.renderscript.Program.TextureType; +import android.util.Log; + +// This is where the scenegraph and the rendered objects are initialized and used +public class TestAppRS { + + private static String modelName = "orientation_test.dae"; + private static String TAG = "TestAppRS"; + private static String mFilePath = ""; + + int mWidth; + int mHeight; + + boolean mUseBlur; + + TestAppLoadingScreen mLoadingScreen; + + // Used to asynchronously load scene elements like meshes and transform hierarchies + SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() { + public void run() { + prepareToRender(mLoadedScene); + } + }; + + // Top level class that initializes all the elements needed to use the scene graph + SceneManager mSceneManager; + + // Used to move the camera around in the 3D world + TouchHandler mTouchHandler; + + private Resources mRes; + private RenderScriptGL mRS; + + // Shaders + private FragmentShader mPaintF; + private FragmentShader mLightsF; + private FragmentShader mLightsDiffF; + private FragmentShader mAluminumF; + private FragmentShader mPlasticF; + private FragmentShader mDiffuseF; + private FragmentShader mTextureF; + private VertexShader mGenericV; + + Scene mActiveScene; + + // This is a part of the test app, it's used to tests multiple render passes and is toggled + // on and off in the menu, off by default + void toggleBlur() { + mUseBlur = !mUseBlur; + + mActiveScene.clearRenderPasses(); + initRenderPasses(); + mActiveScene.initRenderPassRS(mRS, mSceneManager); + + // This is just a hardcoded object in the scene that gets turned on and off for the demo + // to make things look a bit better. This could be deleted in the cleanup + Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); + if (plane != null) { + plane.setVisible(!mUseBlur); + } + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mUseBlur = false; + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + + mTouchHandler = new TouchHandler(); + + mSceneManager = SceneManager.getInstance(); + // Initializes all the RS specific scenegraph elements + mSceneManager.initRS(mRS, mRes, mWidth, mHeight); + + mLoadingScreen = new TestAppLoadingScreen(mRS, mRes); + + // Initi renderscript stuff specific to the app. This will need to be abstracted out later. + FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight); + initPaintShaders(); + + // Load a scene to render + mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback); + } + + // When a new model file is selected from the UI, this function gets called to init everything + void loadModel(String path) { + mLoadingScreen.showLoadingScreen(true); + mActiveScene.destroyRS(); + mSceneManager.loadModel(path, mLoadedCallback); + } + + public void onActionDown(float x, float y) { + mTouchHandler.onActionDown(x, y); + } + + public void onActionScale(float scale) { + mTouchHandler.onActionScale(scale); + } + + public void onActionMove(float x, float y) { + mTouchHandler.onActionMove(x, y); + } + + FragmentShader createFromResource(int id, boolean addCubemap, Type constType) { + FragmentShader.Builder fb = new FragmentShader.Builder(mRS); + fb.setShaderConst(constType); + fb.setShader(mRes, id); + fb.addTexture(TextureType.TEXTURE_2D, "diffuse"); + if (addCubemap) { + fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection"); + } + FragmentShader pf = fb.create(); + pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0); + if (addCubemap) { + pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1); + } + return pf; + } + + private void initPaintShaders() { + mGenericV = SceneManager.getDefaultVS(); + + ScriptField_CameraParams camParams = new ScriptField_CameraParams(mRS, 1); + Type camParamType = camParams.getAllocation().getType(); + ScriptField_LightParams lightParams = new ScriptField_LightParams(mRS, 1); + + mPaintF = createFromResource(R.raw.paintf, true, camParamType); + // Assign a reflection map + TextureCube envCube = new TextureCube("sdcard/scenegraph/", "cube_env.png"); + mPaintF.appendSourceParams(new TextureParam("reflection", envCube)); + + mAluminumF = createFromResource(R.raw.metal, true, camParamType); + TextureCube diffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png"); + mAluminumF.appendSourceParams(new TextureParam("reflection", diffCube)); + + mPlasticF = createFromResource(R.raw.plastic, false, camParamType); + mDiffuseF = createFromResource(R.raw.diffuse, false, camParamType); + mTextureF = SceneManager.getTextureFS(); + + FragmentShader.Builder fb = new FragmentShader.Builder(mRS); + fb.setObjectConst(lightParams.getAllocation().getType()); + fb.setShader(mRes, R.raw.plastic_lights); + mLightsF = fb.create(); + + fb = new FragmentShader.Builder(mRS); + fb.setObjectConst(lightParams.getAllocation().getType()); + fb.setShader(mRes, R.raw.diffuse_lights); + mLightsDiffF = fb.create(); + + FullscreenBlur.initShaders(mRes, mRS); + } + + void initRenderPasses() { + ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables(); + int numDraw = allDraw.size(); + + if (mUseBlur) { + FullscreenBlur.addBlurPasses(mActiveScene, mRS, mTouchHandler.getCamera()); + } + + RenderPass mainPass = new RenderPass(); + mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f)); + mainPass.setShouldClearColor(true); + mainPass.setClearDepth(1.0f); + mainPass.setShouldClearDepth(true); + mainPass.setCamera(mTouchHandler.getCamera()); + for (int i = 0; i < numDraw; i ++) { + mainPass.appendRenderable((Renderable)allDraw.get(i)); + } + mActiveScene.appendRenderPass(mainPass); + + if (mUseBlur) { + FullscreenBlur.addCompositePass(mActiveScene, mRS, mTouchHandler.getCamera()); + } + } + + private void addShadersToScene() { + mActiveScene.appendShader(mPaintF); + mActiveScene.appendShader(mLightsF); + mActiveScene.appendShader(mLightsDiffF); + mActiveScene.appendShader(mAluminumF); + mActiveScene.appendShader(mPlasticF); + mActiveScene.appendShader(mDiffuseF); + mActiveScene.appendShader(mTextureF); + } + + public void prepareToRender(Scene s) { + mSceneManager.setActiveScene(s); + mActiveScene = s; + mTouchHandler.init(mActiveScene); + addShadersToScene(); + RenderState plastic = new RenderState(mGenericV, mPlasticF, null, null); + RenderState diffuse = new RenderState(mGenericV, mDiffuseF, null, null); + RenderState paint = new RenderState(mGenericV, mPaintF, null, null); + RenderState aluminum = new RenderState(mGenericV, mAluminumF, null, null); + RenderState lights = new RenderState(mGenericV, mLightsF, null, null); + RenderState diff_lights = new RenderState(mGenericV, mLightsDiffF, null, null); + RenderState diff_lights_no_cull = new RenderState(mGenericV, mLightsDiffF, null, + ProgramRaster.CULL_NONE(mRS)); + RenderState glassTransp = new RenderState(mGenericV, mPaintF, + ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null); + RenderState texState = new RenderState(mGenericV, mTextureF, null, null); + + initRenderPasses(); + + mActiveScene.assignRenderState(plastic); + + mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$"); + + mActiveScene.assignRenderStateToMaterial(paint, "^Paint"); + mActiveScene.assignRenderStateToMaterial(paint, "^Carbon"); + mActiveScene.assignRenderStateToMaterial(paint, "^Glass"); + mActiveScene.assignRenderStateToMaterial(paint, "^MainGlass"); + + mActiveScene.assignRenderStateToMaterial(aluminum, "^Metal"); + mActiveScene.assignRenderStateToMaterial(aluminum, "^Brake"); + + mActiveScene.assignRenderStateToMaterial(glassTransp, "^GlassLight"); + + mActiveScene.assignRenderStateToMaterial(lights, "^LightBlinn"); + mActiveScene.assignRenderStateToMaterial(diff_lights, "^LightLambert"); + mActiveScene.assignRenderStateToMaterial(diff_lights_no_cull, "^LightLambertNoCull"); + mActiveScene.assignRenderStateToMaterial(texState, "^TextureOnly"); + + Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1"); + if (plane != null) { + plane.setRenderState(texState); + plane.setVisible(!mUseBlur); + } + + long start = System.currentTimeMillis(); + mActiveScene.initRS(); + long end = System.currentTimeMillis(); + Log.v("TIMER", "Scene init time: " + (end - start)); + + mLoadingScreen.showLoadingScreen(false); + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java new file mode 100644 index 0000000..33ca1b8 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; + +public class TestAppView extends RSSurfaceView { + + public TestAppView(Context context) { + super(context); + mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); + } + + private RenderScriptGL mRS; + TestAppRS mRender; + + private ScaleGestureDetector mScaleDetector; + private static final int INVALID_POINTER_ID = -1; + private int mActivePointerId = INVALID_POINTER_ID; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + sc.setDepth(16, 24); + sc.setSamples(1, 2, 1); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new TestAppRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if (mRS != null) { + mRender = null; + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) { + mScaleDetector.onTouchEvent(ev); + + boolean ret = false; + float x = ev.getX(); + float y = ev.getY(); + + final int action = ev.getAction(); + + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: { + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(0); + ret = true; + break; + } + case MotionEvent.ACTION_MOVE: { + if (!mScaleDetector.isInProgress()) { + mRender.onActionMove(x, y); + } + mRender.onActionDown(x, y); + ret = true; + break; + } + + case MotionEvent.ACTION_UP: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_CANCEL: { + mActivePointerId = INVALID_POINTER_ID; + break; + } + + case MotionEvent.ACTION_POINTER_UP: { + final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) + >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; + final int pointerId = ev.getPointerId(pointerIndex); + if (pointerId == mActivePointerId) { + // This was our active pointer going up. Choose a new + // active pointer and adjust accordingly. + final int newPointerIndex = pointerIndex == 0 ? 1 : 0; + x = ev.getX(newPointerIndex); + y = ev.getY(newPointerIndex); + mRender.onActionDown(x, y); + mActivePointerId = ev.getPointerId(newPointerIndex); + } + break; + } + } + + return ret; + } + + private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { + @Override + public boolean onScale(ScaleGestureDetector detector) { + mRender.onActionScale(detector.getScaleFactor()); + return true; + } + } +} + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java new file mode 100644 index 0000000..d0f9797 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.testapp; + +import android.util.Log; +import android.renderscript.Float3; +import com.android.scenegraph.*; +import com.android.scenegraph.CompoundTransform.RotateComponent; +import com.android.scenegraph.CompoundTransform.TranslateComponent; + +public class TouchHandler { + private static String TAG = "TouchHandler"; + + float mLastX; + float mLastY; + + float mRotateXValue; + float mRotateYValue; + Float3 mDistValue; + Float3 mPosValue; + + CompoundTransform mCameraRig; + RotateComponent mRotateX; + RotateComponent mRotateY; + TranslateComponent mDist; + TranslateComponent mPosition; + Camera mCamera; + + public void init(Scene scene) { + // Some initial values for camera position + mRotateXValue = -20; + mRotateYValue = 0; + mDistValue = new Float3(0, 0, 45); + mPosValue = new Float3(0, 4, 0); + + // Make a camera transform we can manipulate + mCameraRig = scene.appendNewCompoundTransform(); + mCameraRig.setName("CameraRig"); + + mPosition = mCameraRig.addTranslate("Position", mPosValue); + mRotateY = mCameraRig.addRotate("RotateY", new Float3(0, 1, 0), mRotateYValue); + mRotateX = mCameraRig.addRotate("RotateX", new Float3(1, 0, 0), mRotateXValue); + mDist = mCameraRig.addTranslate("Distance", mDistValue); + + mCamera = scene.appendNewCamera(); + mCamera.setTransform(mCameraRig); + } + + public Camera getCamera() { + return mCamera; + } + + public void onActionDown(float x, float y) { + mLastX = x; + mLastY = y; + } + + public void onActionScale(float scale) { + if (mDist == null) { + return; + } + mDistValue.z *= 1.0f / scale; + mDistValue.z = Math.max(10.0f, Math.min(mDistValue.z, 150.0f)); + mDist.setValue(mDistValue); + } + + public void onActionMove(float x, float y) { + if (mRotateX == null) { + return; + } + + float dx = mLastX - x; + float dy = mLastY - y; + + if (Math.abs(dy) <= 2.0f) { + dy = 0.0f; + } + if (Math.abs(dx) <= 2.0f) { + dx = 0.0f; + } + + mRotateYValue += dx * 0.25f; + mRotateYValue %= 360.0f; + + mRotateXValue += dy * 0.25f; + mRotateXValue = Math.max(mRotateXValue , -80.0f); + mRotateXValue = Math.min(mRotateXValue , 0.0f); + + mRotateX.setAngle(mRotateXValue); + mRotateY.setAngle(mRotateYValue); + + mLastX = x; + mLastY = y; + } +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs new file mode 100644 index 0000000..997a1a7 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs @@ -0,0 +1,86 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.testapp) + +#include "rs_graphics.rsh" +#include "test_app.rsh" + +// Making sure these get reflected +FBlurOffsets *blurExport; +VShaderInputs *iExport; +FShaderParams *fConst; +FShaderLightParams *fConts2; +VSParams *vConst2; +VObjectParams *vConst3; + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +rs_allocation gRobotTex; +rs_mesh gRobotMesh; + +rs_program_store gPFSBackground; + +float gRotate; + +void init() { + gRotate = 0.0f; +} + +static int pos = 50; +static float gRotateY = 120.0f; +static float3 gLookAt = 0; +static float gZoom = 50.0f; +static void displayLoading() { + if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) { + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gRobotTex); + + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + // Position our models on the screen + gRotateY += rsGetDt()*100; + rsMatrixTranslate(&matrix, 0, 0, -gZoom); + rsMatrixRotate(&matrix, 20.0f, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); + rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f); + rsgProgramVertexLoadModelMatrix(&matrix); + rsgDrawMesh(gRobotMesh); + } + + uint width = rsgGetWidth(); + uint height = rsgGetHeight(); + int left = 0, right = 0, top = 0, bottom = 0; + const char* text = "Initializing..."; + rsgMeasureText(text, &left, &right, &top, &bottom); + int centeredPos = width / 2 - (right - left) / 2; + rsgDrawText(text, centeredPos, height / 2 + height / 10); +} + +int root(void) { + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + displayLoading(); + return 30; +} diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh new file mode 100644 index 0000000..5fbcbb2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh @@ -0,0 +1,52 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.testapp) + +// Helpers +typedef struct ViewProjParams { + rs_matrix4x4 viewProj; +} VSParams; + +typedef struct ModelParams { + rs_matrix4x4 model; +} VObjectParams; + +typedef struct CameraParams { + float4 cameraPos; +} FShaderParams; + +typedef struct LightParams { + float4 lightPos_0; + float4 lightColor_0; + float4 lightPos_1; + float4 lightColor_1; + float4 cameraPos; + float4 diffuse; +} FShaderLightParams; + +typedef struct BlurOffsets { + float blurOffset0; + float blurOffset1; + float blurOffset2; + float blurOffset3; +} FBlurOffsets; + +typedef struct VertexShaderInputs { + float4 position; + float3 normal; + float2 texture0; +} VShaderInputs; diff --git a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs index 53f10f9..ae32e3a 100644 --- a/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs +++ b/tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs @@ -57,6 +57,14 @@ static float gZoom; static float gLastX; static float gLastY; +static float3 toFloat3(float x, float y, float z) { + float3 f; + f.x = x; + f.y = y; + f.z = z; + return f; +} + void onActionDown(float x, float y) { gLastX = x; gLastY = y; @@ -112,8 +120,8 @@ void updateMeshInfo() { rsgMeshComputeBoundingBox(info->mMesh, &minX, &minY, &minZ, &maxX, &maxY, &maxZ); - info->bBoxMin = (minX, minY, minZ); - info->bBoxMax = (maxX, maxY, maxZ); + info->bBoxMin = toFloat3(minX, minY, minZ); + info->bBoxMax = toFloat3(maxX, maxY, maxZ); gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; } gLookAt = gLookAt / (float)size; diff --git a/tests/RenderScriptTests/SurfaceTexture/Android.mk b/tests/RenderScriptTests/SurfaceTexture/Android.mk new file mode 100644 index 0000000..bbd4d55 --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/Android.mk @@ -0,0 +1,29 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +# TODO: build fails with this set +# LOCAL_SDK_VERSION := current + +LOCAL_PACKAGE_NAME := RsSurfaceTextureOpaque + +include $(BUILD_PACKAGE) diff --git a/tests/RenderScriptTests/SurfaceTexture/AndroidManifest.xml b/tests/RenderScriptTests/SurfaceTexture/AndroidManifest.xml new file mode 100644 index 0000000..8aaa239 --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/AndroidManifest.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.android.rs.sto"> + <uses-sdk android:minSdkVersion="14" /> + <uses-permission android:name="android.permission.CAMERA" /> + <uses-feature android:name="android.hardware.camera" /> + <uses-feature android:name="android.hardware.camera.autofocus" /> + + <application + android:label="RsSurfaceTextureOpaque" + android:hardwareAccelerated="true" + android:icon="@drawable/test_pattern"> + + <activity android:name="SurfaceTextureOpaque"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/SurfaceTexture/res/drawable/test_pattern.png b/tests/RenderScriptTests/SurfaceTexture/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/res/drawable/test_pattern.png diff --git a/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/CameraCapture.java b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/CameraCapture.java new file mode 100644 index 0000000..afdab41 --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/CameraCapture.java @@ -0,0 +1,234 @@ +/* + * 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.example.android.rs.sto; + +import android.graphics.SurfaceTexture; +import android.hardware.Camera; +import android.os.SystemClock; +import android.util.Log; + +import java.io.IOException; +import java.util.List; + +public class CameraCapture { + + public interface CameraFrameListener { + public void onNewCameraFrame(); + } + + static final int FRAMES_PER_SEC = 30; + + private Camera mCamera; + private SurfaceTexture mSurfaceTexture; + + private int mProgram; + + private int mCameraTransformHandle; + private int mTexSamplerHandle; + private int mTexCoordHandle; + private int mPosCoordHandle; + + private float[] mCameraTransform = new float[16]; + + private int mCameraId = 0; + private int mWidth; + private int mHeight; + + private long mStartCaptureTime = 0; + + private boolean mNewFrameAvailable = false; + private boolean mIsOpen = false; + + private CameraFrameListener mListener; + + public synchronized void beginCapture(int cameraId, int width, int height, + SurfaceTexture st) { + mCameraId = cameraId; + mSurfaceTexture = st; + + // Open the camera + openCamera(width, height); + + // Start the camera + mStartCaptureTime = SystemClock.elapsedRealtime(); + mCamera.startPreview(); + mIsOpen = true; + } + + public void getCurrentFrame() { + if (checkNewFrame()) { + if (mStartCaptureTime > 0 && SystemClock.elapsedRealtime() - mStartCaptureTime > 2000) { + // Lock white-balance and exposure for effects + Log.i("CC", "Locking white-balance and exposure!"); + Camera.Parameters params = mCamera.getParameters(); + params.setAutoWhiteBalanceLock(true); + params.setAutoExposureLock(true); + //mCamera.setParameters(params); + mStartCaptureTime = 0; + } + + mSurfaceTexture.updateTexImage(); + mSurfaceTexture.getTransformMatrix(mCameraTransform); + + // display it here + } + } + + public synchronized boolean hasNewFrame() { + return mNewFrameAvailable; + } + + public synchronized void endCapture() { + mIsOpen = false; + if (mCamera != null) { + mCamera.release(); + mCamera = null; + mSurfaceTexture = null; + } + } + + public synchronized boolean isOpen() { + return mIsOpen; + } + + public int getWidth() { + return mWidth; + } + + public int getHeight() { + return mHeight; + } + + public void setCameraFrameListener(CameraFrameListener listener) { + mListener = listener; + } + + private void openCamera(int width, int height) { + // Setup camera + mCamera = Camera.open(mCameraId); + mCamera.setParameters(calcCameraParameters(width, height)); + + // Create camera surface texture + try { + mCamera.setPreviewTexture(mSurfaceTexture); + } catch (IOException e) { + throw new RuntimeException("Could not bind camera surface texture: " + + e.getMessage() + "!"); + } + + // Connect SurfaceTexture to callback + mSurfaceTexture.setOnFrameAvailableListener(onCameraFrameAvailableListener); + } + + private Camera.Parameters calcCameraParameters(int width, int height) { + Camera.Parameters params = mCamera.getParameters(); + params.setPreviewSize(mWidth, mHeight); + + // Find closest size + int closestSize[] = findClosestSize(width, height, params); + mWidth = closestSize[0]; + mHeight = closestSize[1]; + params.setPreviewSize(mWidth, mHeight); + + // Find closest FPS + int closestRange[] = findClosestFpsRange(FRAMES_PER_SEC, params); + + params.setPreviewFpsRange(closestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX], + closestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); + + return params; + } + + private int[] findClosestSize(int width, int height, Camera.Parameters parameters) { + List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); + int closestWidth = -1; + int closestHeight = -1; + int smallestWidth = previewSizes.get(0).width; + int smallestHeight = previewSizes.get(0).height; + for (Camera.Size size : previewSizes) { + // Best match defined as not being larger in either dimension than + // the requested size, but as close as possible. The below isn't a + // stable selection (reording the size list can give different + // results), but since this is a fallback nicety, that's acceptable. + if ( size.width <= width && + size.height <= height && + size.width >= closestWidth && + size.height >= closestHeight) { + closestWidth = size.width; + closestHeight = size.height; + } + if ( size.width < smallestWidth && + size.height < smallestHeight) { + smallestWidth = size.width; + smallestHeight = size.height; + } + } + if (closestWidth == -1) { + // Requested size is smaller than any listed size; match with smallest possible + closestWidth = smallestWidth; + closestHeight = smallestHeight; + } + int[] closestSize = {closestWidth, closestHeight}; + return closestSize; + } + + private int[] findClosestFpsRange(int fps, Camera.Parameters params) { + List<int[]> supportedFpsRanges = params.getSupportedPreviewFpsRange(); + int[] closestRange = supportedFpsRanges.get(0); + int fpsk = fps * 1000; + int minDiff = 1000000; + for (int[] range : supportedFpsRanges) { + int low = range[Camera.Parameters.PREVIEW_FPS_MIN_INDEX]; + int high = range[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]; + if (low <= fpsk && high >= fpsk) { + int diff = (fpsk - low) + (high - fpsk); + if (diff < minDiff) { + closestRange = range; + minDiff = diff; + } + } + } + Log.i("CC", "Found closest range: " + + closestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] + " - " + + closestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]); + return closestRange; + } + + private synchronized void signalNewFrame() { + mNewFrameAvailable = true; + if (mListener != null) { + mListener.onNewCameraFrame(); + } + } + + private synchronized boolean checkNewFrame() { + if (mNewFrameAvailable) { + mNewFrameAvailable = false; + return true; + } + return false; + } + + private SurfaceTexture.OnFrameAvailableListener onCameraFrameAvailableListener = + new SurfaceTexture.OnFrameAvailableListener() { + @Override + public void onFrameAvailable(SurfaceTexture surfaceTexture) { + signalNewFrame(); + } + }; +} diff --git a/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaque.java b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaque.java new file mode 100644 index 0000000..a51edaa --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaque.java @@ -0,0 +1,71 @@ +/* + * 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.example.android.rs.sto; + +import android.app.Activity; +import android.os.Bundle; +import android.provider.Settings.System; +import android.util.Log; +import android.view.View; +import android.graphics.SurfaceTexture; + +import java.lang.Runtime; + +public class SurfaceTextureOpaque extends Activity { + private SurfaceTextureOpaqueView mView; + CameraCapture mCC; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mView = new SurfaceTextureOpaqueView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + super.onResume(); + mView.resume(); + startCamera(); + } + + @Override + protected void onPause() { + super.onPause(); + mView.pause(); + mCC.endCapture(); + } + + cfl mCFL; + public void startCamera() { + mCC = new CameraCapture(); + mCFL = new cfl(); + + mCC.setCameraFrameListener(mCFL); + + mCC.beginCapture(1, 640, 480, mView.getST()); + } + + public class cfl implements CameraCapture.CameraFrameListener { + public void onNewCameraFrame() { + mView.mRender.newFrame(); + } + } + +} + diff --git a/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueRS.java b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueRS.java new file mode 100644 index 0000000..b638b7d --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueRS.java @@ -0,0 +1,83 @@ +/* + * 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.example.android.rs.sto; + +import android.content.res.Resources; +import android.renderscript.*; +import android.graphics.SurfaceTexture; +import android.util.Log; + + +public class SurfaceTextureOpaqueRS { + static final private int NUM_CAMERA_PREVIEW_BUFFERS = 2; + + public SurfaceTextureOpaqueRS() { + } + + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_sto mScript; + private SurfaceTexture mST; + private Allocation mSto; + private Allocation mSto2; + private Allocation mRto; + private ProgramFragment mPF; + + public void init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + + Type.Builder tb = new Type.Builder(mRS, Element.RGBA_8888(mRS)); + tb.setX(640); + tb.setY(480); + mSto = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_GRAPHICS_TEXTURE | + Allocation.USAGE_IO_INPUT); + mRto = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_GRAPHICS_RENDER_TARGET | + Allocation.USAGE_IO_OUTPUT); + mSto2 = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_GRAPHICS_TEXTURE | + Allocation.USAGE_IO_INPUT); + mST = mSto.getSurfaceTexture(); + mRto.setSurfaceTexture(mSto2.getSurfaceTexture()); + + ProgramFragmentFixedFunction.Builder pfb = new ProgramFragmentFixedFunction.Builder(rs); + pfb.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, + ProgramFragmentFixedFunction.Builder.Format.RGBA, 0); + mPF = pfb.create(); + mPF.bindSampler(Sampler.CLAMP_NEAREST(mRS), 0); + rs.bindProgramFragment(mPF); + + mScript = new ScriptC_sto(mRS, mRes, R.raw.sto); + mScript.set_sto(mSto); + mScript.set_rto(mRto); + mScript.set_sto2(mSto2); + mScript.set_pf(mPF); + + mRS.bindRootScript(mScript); + + + android.util.Log.v("sto", "Init complete"); + } + + SurfaceTexture getST() { + return mST; + } + + public void newFrame() { + mSto.ioReceive(); + } + +} diff --git a/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueView.java b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueView.java new file mode 100644 index 0000000..f5e49f2 --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueView.java @@ -0,0 +1,60 @@ +/* + * 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.example.android.rs.sto; + + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScriptGL; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.SurfaceTexture; +import android.util.Log; + +public class SurfaceTextureOpaqueView extends RSSurfaceView { + + public SurfaceTextureOpaqueView(Context context) { + super(context); + } + + RenderScriptGL mRS; + SurfaceTextureOpaqueRS mRender; + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + SurfaceTexture getST() { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScriptGL(sc); + mRender = new SurfaceTextureOpaqueRS(); + mRender.init(mRS, getResources()); + return mRender.getST(); + } + +} + + diff --git a/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/sto.rs b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/sto.rs new file mode 100644 index 0000000..efa901a --- /dev/null +++ b/tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/sto.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. + */ + +#pragma version(1) +#pragma rs java_package_name(com.example.android.rs.sto) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + + +rs_program_fragment pf; +rs_allocation sto; // camera in +rs_allocation sto2; +rs_allocation rto; // render target + +int root() { + rsgBindTexture(pf, 0, sto); + +#if 1 + rsgBindColorTarget(rto, 0); + + rsgClearColor(0.f, 1.f, 0.f, 1.f); + rsgDrawQuadTexCoords(0, 0, 0, 0,0, + 0,500,0, 1,0, + 500,500,0, 1, 1, + 500, 0, 0, 0, 1 ); + rsgClearColorTarget(0); + + // io ops + rsAllocationIoSend(rto); + rsAllocationIoReceive(sto2); + + rsgBindTexture(pf, 0, sto2); +#endif + + rsgClearColor(0.f, 1.f, 0.f, 1.f); + rsgDrawQuadTexCoords(0, 0, 0, 0,0, + 0,500,0, 1,0, + 500,500,0, 1, 1, + 500, 0, 0, 0, 1 ); + + return 1; +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index c038478..22e1bff 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 The Android Open Source Project + * Copyright (C) 2008-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. @@ -65,15 +65,27 @@ public class RSTestCore { unitTests = new ArrayList<UnitTest>(); unitTests.add(new UT_primitives(this, mRes, mCtx)); + unitTests.add(new UT_constant(this, mRes, mCtx)); unitTests.add(new UT_vector(this, mRes, mCtx)); + unitTests.add(new UT_array_init(this, mRes, mCtx)); + unitTests.add(new UT_convert(this, mRes, mCtx)); unitTests.add(new UT_rsdebug(this, mRes, mCtx)); unitTests.add(new UT_rstime(this, mRes, mCtx)); unitTests.add(new UT_rstypes(this, mRes, mCtx)); unitTests.add(new UT_alloc(this, mRes, mCtx)); unitTests.add(new UT_refcount(this, mRes, mCtx)); unitTests.add(new UT_foreach(this, mRes, mCtx)); + unitTests.add(new UT_noroot(this, mRes, mCtx)); + unitTests.add(new UT_atomic(this, mRes, mCtx)); + unitTests.add(new UT_struct(this, mRes, mCtx)); unitTests.add(new UT_math(this, mRes, mCtx)); + unitTests.add(new UT_mesh(this, mRes, mCtx)); + unitTests.add(new UT_element(this, mRes, mCtx)); + unitTests.add(new UT_sampler(this, mRes, mCtx)); + unitTests.add(new UT_program_store(this, mRes, mCtx)); + unitTests.add(new UT_program_raster(this, mRes, mCtx)); unitTests.add(new UT_fp_mad(this, mRes, mCtx)); + /* unitTests.add(new UnitTest(null, "<Pass>", 1)); unitTests.add(new UnitTest()); @@ -91,7 +103,7 @@ public class RSTestCore { for (int i = 0; i < uta.length; i++) { ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item(); listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT); - listElem.result = uta[i].result; + listElem.result = uta[i].getResult(); mListAllocs.set(listElem, i, false); uta[i].setItem(listElem); } diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_array_init.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_array_init.java new file mode 100644 index 0000000..b98b753 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_array_init.java @@ -0,0 +1,95 @@ +/* + * 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.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_array_init extends UnitTest { + private Resources mRes; + + protected UT_array_init(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Array Init", ctx); + mRes = res; + } + + private void checkInit(ScriptC_array_init s) { + float[] fa = s.get_fa(); + _RS_ASSERT("fa[0] == 1.0", fa[0] == 1.0); + _RS_ASSERT("fa[1] == 9.9999f", fa[1] == 9.9999f); + _RS_ASSERT("fa[2] == 0", fa[2] == 0); + _RS_ASSERT("fa[3] == 0", fa[3] == 0); + _RS_ASSERT("fa.length == 4", fa.length == 4); + + double[] da = s.get_da(); + _RS_ASSERT("da[0] == 7.0", da[0] == 7.0); + _RS_ASSERT("da[1] == 8.88888", da[1] == 8.88888); + _RS_ASSERT("da.length == 2", da.length == 2); + + byte[] ca = s.get_ca(); + _RS_ASSERT("ca[0] == 'a'", ca[0] == 'a'); + _RS_ASSERT("ca[1] == 7", ca[1] == 7); + _RS_ASSERT("ca[2] == 'b'", ca[2] == 'b'); + _RS_ASSERT("ca[3] == 'c'", ca[3] == 'c'); + _RS_ASSERT("ca.length == 4", ca.length == 4); + + short[] sa = s.get_sa(); + _RS_ASSERT("sa[0] == 1", sa[0] == 1); + _RS_ASSERT("sa[1] == 1", sa[1] == 1); + _RS_ASSERT("sa[2] == 2", sa[2] == 2); + _RS_ASSERT("sa[3] == 3", sa[3] == 3); + _RS_ASSERT("sa.length == 4", sa.length == 4); + + int[] ia = s.get_ia(); + _RS_ASSERT("ia[0] == 5", ia[0] == 5); + _RS_ASSERT("ia[1] == 8", ia[1] == 8); + _RS_ASSERT("ia[2] == 0", ia[2] == 0); + _RS_ASSERT("ia[3] == 0", ia[3] == 0); + _RS_ASSERT("ia.length == 4", ia.length == 4); + + long[] la = s.get_la(); + _RS_ASSERT("la[0] == 13", la[0] == 13); + _RS_ASSERT("la[1] == 21", la[1] == 21); + _RS_ASSERT("la.length == 4", la.length == 2); + + long[] lla = s.get_lla(); + _RS_ASSERT("lla[0] == 34", lla[0] == 34); + _RS_ASSERT("lla[1] == 0", lla[1] == 0); + _RS_ASSERT("lla[2] == 0", lla[2] == 0); + _RS_ASSERT("lla[3] == 0", lla[3] == 0); + _RS_ASSERT("lla.length == 4", lla.length == 4); + + boolean[] ba = s.get_ba(); + _RS_ASSERT("ba[0] == true", ba[0] == true); + _RS_ASSERT("ba[1] == false", ba[1] == false); + _RS_ASSERT("ba[2] == false", ba[2] == false); + _RS_ASSERT("ba.length == 3", ba.length == 3); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_array_init s = new ScriptC_array_init(pRS, mRes, R.raw.array_init); + pRS.setMessageHandler(mRsMessage); + checkInit(s); + s.invoke_array_init_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + passTest(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java new file mode 100644 index 0000000..267c5b2 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java @@ -0,0 +1,40 @@ +/* + * 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.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_atomic extends UnitTest { + private Resources mRes; + + protected UT_atomic(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Atomics", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_atomic s = new ScriptC_atomic(pRS, mRes, R.raw.atomic); + pRS.setMessageHandler(mRsMessage); + s.invoke_atomic_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_constant.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_constant.java new file mode 100644 index 0000000..adda5a3 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_constant.java @@ -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. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_constant extends UnitTest { + private Resources mRes; + + protected UT_constant(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Const", ctx); + mRes = res; + } + + private void Assert(boolean b) { + if (!b) { + failTest(); + } + } + + public void run() { + Assert(ScriptC_constant.const_floatTest == 1.99f); + Assert(ScriptC_constant.const_doubleTest == 2.05); + Assert(ScriptC_constant.const_charTest == -8); + Assert(ScriptC_constant.const_shortTest == -16); + Assert(ScriptC_constant.const_intTest == -32); + Assert(ScriptC_constant.const_longTest == 17179869184l); + Assert(ScriptC_constant.const_longlongTest == 68719476736l); + + Assert(ScriptC_constant.const_ucharTest == 8); + Assert(ScriptC_constant.const_ushortTest == 16); + Assert(ScriptC_constant.const_uintTest == 32); + Assert(ScriptC_constant.const_ulongTest == 4611686018427387904L); + Assert(ScriptC_constant.const_int64_tTest == -17179869184l); + Assert(ScriptC_constant.const_uint64_tTest == 117179869184l); + + Assert(ScriptC_constant.const_boolTest == true); + + passTest(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java new file mode 100644 index 0000000..4fc6c55 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java @@ -0,0 +1,40 @@ +/* + * 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.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_convert extends UnitTest { + private Resources mRes; + + protected UT_convert(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Convert", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_convert s = new ScriptC_convert(pRS, mRes, R.raw.convert); + pRS.setMessageHandler(mRsMessage); + s.invoke_convert_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java new file mode 100644 index 0000000..3e2a2ca --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Element.*; +import android.renderscript.Element.DataKind.*; +import android.renderscript.Element.DataType.*; + +public class UT_element extends UnitTest { + private Resources mRes; + + Element simpleElem; + Element complexElem; + + final String subElemNames[] = { + "subElem0", + "subElem1", + "subElem2", + "arrayElem0", + "arrayElem1", + "subElem3", + "subElem4", + "subElem5", + "subElem6", + "subElem_7", + }; + + final int subElemArraySizes[] = { + 1, + 1, + 1, + 2, + 5, + 1, + 1, + 1, + 1, + 1, + }; + + final int subElemOffsets[] = { + 0, + 4, + 8, + 12, + 20, + 40, + 44, + 48, + 64, + 80, + }; + + protected UT_element(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Element", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_element s) { + simpleElem = Element.F32_3(RS); + complexElem = ScriptField_ComplexStruct.createElement(RS); + s.set_simpleElem(simpleElem); + s.set_complexElem(complexElem); + + ScriptField_ComplexStruct data = new ScriptField_ComplexStruct(RS, 1); + s.bind_complexStruct(data); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_element s = new ScriptC_element(pRS, mRes, R.raw.element); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_element_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + + int subElemCount = simpleElem.getSubElementCount(); + _RS_ASSERT("subElemCount == 0", subElemCount == 0); + _RS_ASSERT("simpleElem.getDataKind() == USER", + simpleElem.getDataKind() == DataKind.USER); + _RS_ASSERT("simpleElem.getDataType() == FLOAT_32", + simpleElem.getDataType() == DataType.FLOAT_32); + + subElemCount = complexElem.getSubElementCount(); + _RS_ASSERT("subElemCount == 10", subElemCount == 10); + _RS_ASSERT("complexElem.getDataKind() == USER", + complexElem.getDataKind() == DataKind.USER); + _RS_ASSERT("complexElemsimpleElem.getDataType() == NONE", + complexElem.getDataType() == DataType.NONE); + _RS_ASSERT("complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof", + complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof); + + for (int i = 0; i < subElemCount; i ++) { + _RS_ASSERT("complexElem.getSubElement(i) != null", + complexElem.getSubElement(i) != null); + _RS_ASSERT("complexElem.getSubElementName(i).equals(subElemNames[i])", + complexElem.getSubElementName(i).equals(subElemNames[i])); + _RS_ASSERT("complexElem.getSubElementArraySize(i) == subElemArraySizes[i]", + complexElem.getSubElementArraySize(i) == subElemArraySizes[i]); + _RS_ASSERT("complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]", + complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]); + } + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + passTest(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java index 1d2555e..04e9270 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2011-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. @@ -48,6 +48,9 @@ public class UT_foreach extends UnitTest { pRS.setMessageHandler(mRsMessage); initializeGlobals(pRS, s); s.forEach_root(A); + s.invoke_verify_root(); + s.forEach_foo(A, A); + s.invoke_verify_foo(); s.invoke_foreach_test(); pRS.finish(); waitForMessage(); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java new file mode 100644 index 0000000..0c93702 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Mesh.*; + +public class UT_mesh extends UnitTest { + private Resources mRes; + + Mesh mesh; + + protected UT_mesh(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Mesh", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_mesh s) { + Allocation vAlloc0 = Allocation.createSized(RS, Element.F32(RS), 10); + Allocation vAlloc1 = Allocation.createSized(RS, Element.F32_2(RS), 10); + + Allocation iAlloc0 = Allocation.createSized(RS, Element.I16(RS), 10); + Allocation iAlloc2 = Allocation.createSized(RS, Element.I16(RS), 10); + + Mesh.AllocationBuilder mBuilder = new Mesh.AllocationBuilder(RS); + mBuilder.addVertexAllocation(vAlloc0); + mBuilder.addVertexAllocation(vAlloc1); + + mBuilder.addIndexSetAllocation(iAlloc0, Primitive.POINT); + mBuilder.addIndexSetType(Primitive.LINE); + mBuilder.addIndexSetAllocation(iAlloc2, Primitive.TRIANGLE); + + s.set_mesh(mBuilder.create()); + s.set_vertexAlloc0(vAlloc0); + s.set_vertexAlloc1(vAlloc1); + s.set_indexAlloc0(iAlloc0); + s.set_indexAlloc2(iAlloc2); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_mesh s = new ScriptC_mesh(pRS, mRes, R.raw.mesh); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_mesh_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + passTest(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java new file mode 100644 index 0000000..c660fc5 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011-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.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_noroot extends UnitTest { + private Resources mRes; + private Allocation A; + + protected UT_noroot(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "ForEach (no root)", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_noroot s) { + Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS)); + int X = 5; + int Y = 7; + s.set_dimX(X); + s.set_dimY(Y); + typeBuilder.setX(X).setY(Y); + A = Allocation.createTyped(RS, typeBuilder.create()); + s.bind_a(A); + + return; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_noroot s = new ScriptC_noroot(pRS, mRes, R.raw.noroot); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.forEach_foo(A, A); + s.invoke_verify_foo(); + s.invoke_noroot_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java index b7a65a5..18829c2 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java @@ -92,8 +92,7 @@ public class UT_primitives extends UnitTest { ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives); pRS.setMessageHandler(mRsMessage); if (!initializeGlobals(s)) { - // initializeGlobals failed - result = -1; + failTest(); } else { s.invoke_primitives_test(0, 0); pRS.finish(); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java new file mode 100644 index 0000000..1de4d71 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramRaster; +import android.renderscript.ProgramRaster.CullMode; + +public class UT_program_raster extends UnitTest { + private Resources mRes; + + ProgramRaster pointSpriteEnabled; + ProgramRaster cullMode; + + protected UT_program_raster(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "ProgramRaster", ctx); + mRes = res; + } + + private ProgramRaster.Builder getDefaultBuilder(RenderScript RS) { + ProgramRaster.Builder b = new ProgramRaster.Builder(RS); + b.setCullMode(CullMode.BACK); + b.setPointSpriteEnabled(false); + return b; + } + + private void initializeGlobals(RenderScript RS, ScriptC_program_raster s) { + ProgramRaster.Builder b = getDefaultBuilder(RS); + pointSpriteEnabled = b.setPointSpriteEnabled(true).create(); + b = getDefaultBuilder(RS); + cullMode = b.setCullMode(CullMode.FRONT).create(); + + s.set_pointSpriteEnabled(pointSpriteEnabled); + s.set_cullMode(cullMode); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_program_raster s = new ScriptC_program_raster(pRS, mRes, R.raw.program_raster); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_program_raster_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + _RS_ASSERT("pointSpriteEnabled.getPointSpriteEnabled() == true", + pointSpriteEnabled.getPointSpriteEnabled() == true); + _RS_ASSERT("pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK", + pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK); + + _RS_ASSERT("cullMode.getPointSpriteEnabled() == false", + cullMode.getPointSpriteEnabled() == false); + _RS_ASSERT("cullMode.getCullMode() == ProgramRaster.CullMode.FRONT", + cullMode.getCullMode() == ProgramRaster.CullMode.FRONT); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + passTest(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java new file mode 100644 index 0000000..72a401d --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramStore.BlendDstFunc; +import android.renderscript.ProgramStore.BlendSrcFunc; +import android.renderscript.ProgramStore.Builder; +import android.renderscript.ProgramStore.DepthFunc; + +public class UT_program_store extends UnitTest { + private Resources mRes; + + ProgramStore ditherEnable; + ProgramStore colorRWriteEnable; + ProgramStore colorGWriteEnable; + ProgramStore colorBWriteEnable; + ProgramStore colorAWriteEnable; + ProgramStore blendSrc; + ProgramStore blendDst; + ProgramStore depthWriteEnable; + ProgramStore depthFunc; + + protected UT_program_store(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "ProgramStore", ctx); + mRes = res; + } + + private ProgramStore.Builder getDefaultBuilder(RenderScript RS) { + ProgramStore.Builder b = new ProgramStore.Builder(RS); + b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO, ProgramStore.BlendDstFunc.ZERO); + b.setColorMaskEnabled(false, false, false, false); + b.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + b.setDepthMaskEnabled(false); + b.setDitherEnabled(false); + return b; + } + + private void initializeGlobals(RenderScript RS, ScriptC_program_store s) { + ProgramStore.Builder b = getDefaultBuilder(RS); + ditherEnable = b.setDitherEnabled(true).create(); + + b = getDefaultBuilder(RS); + colorRWriteEnable = b.setColorMaskEnabled(true, false, false, false).create(); + + b = getDefaultBuilder(RS); + colorGWriteEnable = b.setColorMaskEnabled(false, true, false, false).create(); + + b = getDefaultBuilder(RS); + colorBWriteEnable = b.setColorMaskEnabled(false, false, true, false).create(); + + b = getDefaultBuilder(RS); + colorAWriteEnable = b.setColorMaskEnabled(false, false, false, true).create(); + + b = getDefaultBuilder(RS); + blendSrc = b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR, + ProgramStore.BlendDstFunc.ZERO).create(); + + b = getDefaultBuilder(RS); + blendDst = b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO, + ProgramStore.BlendDstFunc.DST_ALPHA).create(); + + b = getDefaultBuilder(RS); + depthWriteEnable = b.setDepthMaskEnabled(true).create(); + + b = getDefaultBuilder(RS); + depthFunc = b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create(); + + s.set_ditherEnable(ditherEnable); + s.set_colorRWriteEnable(colorRWriteEnable); + s.set_colorGWriteEnable(colorGWriteEnable); + s.set_colorBWriteEnable(colorBWriteEnable); + s.set_colorAWriteEnable(colorAWriteEnable); + s.set_blendSrc(blendSrc); + s.set_blendDst(blendDst); + s.set_depthWriteEnable(depthWriteEnable); + s.set_depthFunc(depthFunc); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_program_store s = new ScriptC_program_store(pRS, mRes, R.raw.program_store); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_program_store_test(); + pRS.finish(); + waitForMessage(); + } + + void checkObject(ProgramStore ps, + boolean depthMask, + DepthFunc df, + BlendSrcFunc bsf, + BlendDstFunc bdf, + boolean R, + boolean G, + boolean B, + boolean A, + boolean dither) { + _RS_ASSERT("ps.getDepthMaskEnabled() == depthMask", ps.getDepthMaskEnabled() == depthMask); + _RS_ASSERT("ps.getDepthFunc() == df", ps.getDepthFunc() == df); + _RS_ASSERT("ps.getBlendSrcFunc() == bsf", ps.getBlendSrcFunc() == bsf); + _RS_ASSERT("ps.getBlendDstFunc() == bdf", ps.getBlendDstFunc() == bdf); + _RS_ASSERT("ps.getColorMaskREnabled() == R", ps.getColorMaskREnabled() == R); + _RS_ASSERT("ps.getColorMaskGEnabled() == G", ps.getColorMaskGEnabled() == G); + _RS_ASSERT("ps.getColorMaskBEnabled() == B", ps.getColorMaskBEnabled() == B); + _RS_ASSERT("ps.getColorMaskAEnabled() == A", ps.getColorMaskAEnabled() == A); + _RS_ASSERT("ps.getDitherEnabled() == dither", ps.getDitherEnabled() == dither); + } + + void varyBuilderColorAndDither(ProgramStore.Builder pb, + boolean depthMask, + DepthFunc df, + BlendSrcFunc bsf, + BlendDstFunc bdf) { + for (int r = 0; r <= 1; r++) { + boolean isR = (r == 1); + for (int g = 0; g <= 1; g++) { + boolean isG = (g == 1); + for (int b = 0; b <= 1; b++) { + boolean isB = (b == 1); + for (int a = 0; a <= 1; a++) { + boolean isA = (a == 1); + for (int dither = 0; dither <= 1; dither++) { + boolean isDither = (dither == 1); + pb.setDitherEnabled(isDither); + pb.setColorMaskEnabled(isR, isG, isB, isA); + ProgramStore ps = pb.create(); + checkObject(ps, depthMask, df, bsf, bdf, isR, isG, isB, isA, isDither); + } + } + } + } + } + } + + public void testJavaSide(RenderScript RS) { + for (int depth = 0; depth <= 1; depth++) { + boolean depthMask = (depth == 1); + for (DepthFunc df : DepthFunc.values()) { + for (BlendSrcFunc bsf : BlendSrcFunc.values()) { + for (BlendDstFunc bdf : BlendDstFunc.values()) { + ProgramStore.Builder b = new ProgramStore.Builder(RS); + b.setDepthFunc(df); + b.setDepthMaskEnabled(depthMask); + b.setBlendFunc(bsf, bdf); + varyBuilderColorAndDither(b, depthMask, df, bsf, bdf); + } + } + } + } + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testJavaSide(pRS); + testScriptSide(pRS); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java index f302e1a..21e657c 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java @@ -32,6 +32,7 @@ public class UT_rstime extends UnitTest { RenderScript pRS = RenderScript.create(mCtx); ScriptC_rstime s = new ScriptC_rstime(pRS, mRes, R.raw.rstime); pRS.setMessageHandler(mRsMessage); + s.setTimeZone("America/Los_Angeles"); s.invoke_test_rstime(0, 0); pRS.finish(); waitForMessage(); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java new file mode 100644 index 0000000..c328cf6 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Sampler; +import android.renderscript.Sampler.Value; + +public class UT_sampler extends UnitTest { + private Resources mRes; + + Sampler minification; + Sampler magnification; + Sampler wrapS; + Sampler wrapT; + Sampler anisotropy; + + protected UT_sampler(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Sampler", ctx); + mRes = res; + } + + private Sampler.Builder getDefaultBuilder(RenderScript RS) { + Sampler.Builder b = new Sampler.Builder(RS); + b.setMinification(Value.NEAREST); + b.setMagnification(Value.NEAREST); + b.setWrapS(Value.CLAMP); + b.setWrapT(Value.CLAMP); + b.setAnisotropy(1.0f); + return b; + } + + private void initializeGlobals(RenderScript RS, ScriptC_sampler s) { + Sampler.Builder b = getDefaultBuilder(RS); + b.setMinification(Value.LINEAR_MIP_LINEAR); + minification = b.create(); + + b = getDefaultBuilder(RS); + b.setMagnification(Value.LINEAR); + magnification = b.create(); + + b = getDefaultBuilder(RS); + b.setWrapS(Value.WRAP); + wrapS = b.create(); + + b = getDefaultBuilder(RS); + b.setWrapT(Value.WRAP); + wrapT = b.create(); + + b = getDefaultBuilder(RS); + b.setAnisotropy(8.0f); + anisotropy = b.create(); + + s.set_minification(minification); + s.set_magnification(magnification); + s.set_wrapS(wrapS); + s.set_wrapT(wrapT); + s.set_anisotropy(anisotropy); + } + + private void testScriptSide(RenderScript pRS) { + ScriptC_sampler s = new ScriptC_sampler(pRS, mRes, R.raw.sampler); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_sampler_test(); + pRS.finish(); + waitForMessage(); + } + + private void testJavaSide(RenderScript RS) { + _RS_ASSERT("minification.getMagnification() == Sampler.Value.NEAREST", + minification.getMagnification() == Sampler.Value.NEAREST); + _RS_ASSERT("minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR", + minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR); + _RS_ASSERT("minification.getWrapS() == Sampler.Value.CLAMP", + minification.getWrapS() == Sampler.Value.CLAMP); + _RS_ASSERT("minification.getWrapT() == Sampler.Value.CLAMP", + minification.getWrapT() == Sampler.Value.CLAMP); + _RS_ASSERT("minification.getAnisotropy() == 1.0f", + minification.getAnisotropy() == 1.0f); + + _RS_ASSERT("magnification.getMagnification() == Sampler.Value.LINEAR", + magnification.getMagnification() == Sampler.Value.LINEAR); + _RS_ASSERT("magnification.getMinification() == Sampler.Value.NEAREST", + magnification.getMinification() == Sampler.Value.NEAREST); + _RS_ASSERT("magnification.getWrapS() == Sampler.Value.CLAMP", + magnification.getWrapS() == Sampler.Value.CLAMP); + _RS_ASSERT("magnification.getWrapT() == Sampler.Value.CLAMP", + magnification.getWrapT() == Sampler.Value.CLAMP); + _RS_ASSERT("magnification.getAnisotropy() == 1.0f", + magnification.getAnisotropy() == 1.0f); + + _RS_ASSERT("wrapS.getMagnification() == Sampler.Value.NEAREST", + wrapS.getMagnification() == Sampler.Value.NEAREST); + _RS_ASSERT("wrapS.getMinification() == Sampler.Value.NEAREST", + wrapS.getMinification() == Sampler.Value.NEAREST); + _RS_ASSERT("wrapS.getWrapS() == Sampler.Value.WRAP", + wrapS.getWrapS() == Sampler.Value.WRAP); + _RS_ASSERT("wrapS.getWrapT() == Sampler.Value.CLAMP", + wrapS.getWrapT() == Sampler.Value.CLAMP); + _RS_ASSERT("wrapS.getAnisotropy() == 1.0f", + wrapS.getAnisotropy() == 1.0f); + + _RS_ASSERT("wrapT.getMagnification() == Sampler.Value.NEAREST", + wrapT.getMagnification() == Sampler.Value.NEAREST); + _RS_ASSERT("wrapT.getMinification() == Sampler.Value.NEAREST", + wrapT.getMinification() == Sampler.Value.NEAREST); + _RS_ASSERT("wrapT.getWrapS() == Sampler.Value.CLAMP", + wrapT.getWrapS() == Sampler.Value.CLAMP); + _RS_ASSERT("wrapT.getWrapT() == Sampler.Value.WRAP", + wrapT.getWrapT() == Sampler.Value.WRAP); + _RS_ASSERT("wrapT.getAnisotropy() == 1.0f", + wrapT.getAnisotropy() == 1.0f); + + _RS_ASSERT("anisotropy.getMagnification() == Sampler.Value.NEAREST", + anisotropy.getMagnification() == Sampler.Value.NEAREST); + _RS_ASSERT("anisotropy.getMinification() == Sampler.Value.NEAREST", + anisotropy.getMinification() == Sampler.Value.NEAREST); + _RS_ASSERT("anisotropy.getWrapS() == Sampler.Value.CLAMP", + anisotropy.getWrapS() == Sampler.Value.CLAMP); + _RS_ASSERT("anisotropy.getWrapT() == Sampler.Value.CLAMP", + anisotropy.getWrapT() == Sampler.Value.CLAMP); + _RS_ASSERT("anisotropy.getAnisotropy() == 1.0f", + anisotropy.getAnisotropy() == 8.0f); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + testScriptSide(pRS); + testJavaSide(pRS); + passTest(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java new file mode 100644 index 0000000..2a55686 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java @@ -0,0 +1,55 @@ +/* + * 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.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_struct extends UnitTest { + private Resources mRes; + + protected UT_struct(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Struct", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_struct s = new ScriptC_struct(pRS, mRes, R.raw.struct); + pRS.setMessageHandler(mRsMessage); + + ScriptField_Point2 p = new ScriptField_Point2(pRS, 1); + ScriptField_Point2.Item i = new ScriptField_Point2.Item(); + int val = 100; + i.x = val; + i.y = val; + p.set(i, 0, true); + s.bind_point2(p); + s.invoke_struct_test(val); + pRS.finish(); + waitForMessage(); + + val = 200; + p.set_x(0, val, true); + p.set_y(0, val, true); + s.invoke_struct_test(val); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_vector.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_vector.java index 748701d..0ac09ca 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_vector.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_vector.java @@ -307,7 +307,7 @@ public class UT_vector extends UnitTest { ScriptC_vector s = new ScriptC_vector(pRS, mRes, R.raw.vector); pRS.setMessageHandler(mRsMessage); if (!initializeGlobals(s)) { - result = -1; + failTest(); } else { s.invoke_vector_test(); pRS.finish(); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java index a97ffa7..fbac124 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java @@ -21,7 +21,7 @@ import android.renderscript.RenderScript.RSMessageHandler; public class UnitTest extends Thread { public String name; - public int result; + private int result; private ScriptField_ListAllocs_s.Item mItem; private RSTestCore mRSTC; private boolean msgHandled; @@ -58,12 +58,12 @@ public class UnitTest extends Thread { protected void _RS_ASSERT(String message, boolean b) { if(b == false) { - result = -1; Log.e(name, message + " FAILED"); + failTest(); } } - protected void updateUI() { + private void updateUI() { if (mItem != null) { mItem.result = result; msgHandled = true; @@ -104,6 +104,22 @@ public class UnitTest extends Thread { } } + public int getResult() { + return result; + } + + public void failTest() { + result = -1; + updateUI(); + } + + public void passTest() { + if (result != -1) { + result = 1; + } + updateUI(); + } + public void setItem(ScriptField_ListAllocs_s.Item item) { mItem = item; } diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/array_init.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/array_init.rs new file mode 100644 index 0000000..842249a --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/array_init.rs @@ -0,0 +1,58 @@ +#include "shared.rsh" + +// Testing constant array initialization +float fa[4] = {1.0, 9.9999f}; +double da[2] = {7.0, 8.88888}; +char ca[4] = {'a', 7, 'b', 'c'}; +short sa[4] = {1, 1, 2, 3}; +int ia[4] = {5, 8}; +long la[2] = {13, 21}; +long long lla[4] = {34}; +bool ba[3] = {true, false}; + +void array_init_test() { + bool failed = false; + + _RS_ASSERT(fa[0] == 1.0); + _RS_ASSERT(fa[1] == 9.9999f); + _RS_ASSERT(fa[2] == 0); + _RS_ASSERT(fa[3] == 0); + + _RS_ASSERT(da[0] == 7.0); + _RS_ASSERT(da[1] == 8.88888); + + _RS_ASSERT(ca[0] == 'a'); + _RS_ASSERT(ca[1] == 7); + _RS_ASSERT(ca[2] == 'b'); + _RS_ASSERT(ca[3] == 'c'); + + _RS_ASSERT(sa[0] == 1); + _RS_ASSERT(sa[1] == 1); + _RS_ASSERT(sa[2] == 2); + _RS_ASSERT(sa[3] == 3); + + _RS_ASSERT(ia[0] == 5); + _RS_ASSERT(ia[1] == 8); + _RS_ASSERT(ia[2] == 0); + _RS_ASSERT(ia[3] == 0); + + _RS_ASSERT(la[0] == 13); + _RS_ASSERT(la[1] == 21); + + _RS_ASSERT(lla[0] == 34); + _RS_ASSERT(lla[1] == 0); + _RS_ASSERT(lla[2] == 0); + _RS_ASSERT(lla[3] == 0); + + _RS_ASSERT(ba[0] == true); + _RS_ASSERT(ba[1] == false); + _RS_ASSERT(ba[2] == false); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs new file mode 100644 index 0000000..f0a5041 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs @@ -0,0 +1,77 @@ +#include "shared.rsh" + +// Testing atomic operations +static bool testUMax(uint32_t dst, uint32_t src) { + bool failed = false; + uint32_t old = dst; + uint32_t expect = (dst > src ? dst : src); + uint32_t ret = rsAtomicMax(&dst, src); + _RS_ASSERT(old == ret); + _RS_ASSERT(dst == expect); + return failed; +} + +static bool testUMin(uint32_t dst, uint32_t src) { + bool failed = false; + uint32_t old = dst; + uint32_t expect = (dst < src ? dst : src); + uint32_t ret = rsAtomicMin(&dst, src); + _RS_ASSERT(old == ret); + _RS_ASSERT(dst == expect); + return failed; +} + +static bool testUCas(uint32_t dst, uint32_t cmp, uint32_t swp) { + bool failed = false; + uint32_t old = dst; + uint32_t expect = (dst == cmp ? swp : dst); + uint32_t ret = rsAtomicCas(&dst, cmp, swp); + _RS_ASSERT(old == ret); + _RS_ASSERT(dst == expect); + return failed; +} + +static bool test_atomics() { + bool failed = false; + + failed |= testUMax(5, 6); + failed |= testUMax(6, 5); + failed |= testUMax(5, 0xf0000006); + failed |= testUMax(0xf0000006, 5); + + failed |= testUMin(5, 6); + failed |= testUMin(6, 5); + failed |= testUMin(5, 0xf0000006); + failed |= testUMin(0xf0000006, 5); + + failed |= testUCas(4, 4, 5); + failed |= testUCas(4, 5, 5); + failed |= testUCas(5, 5, 4); + failed |= testUCas(5, 4, 4); + failed |= testUCas(0xf0000004, 0xf0000004, 0xf0000005); + failed |= testUCas(0xf0000004, 0xf0000005, 0xf0000005); + failed |= testUCas(0xf0000005, 0xf0000005, 0xf0000004); + failed |= testUCas(0xf0000005, 0xf0000004, 0xf0000004); + + if (failed) { + rsDebug("test_atomics FAILED", 0); + } + else { + rsDebug("test_atomics PASSED", 0); + } + + return failed; +} + +void atomic_test() { + bool failed = false; + failed |= test_atomics(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/constant.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/constant.rs new file mode 100644 index 0000000..732eaef --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/constant.rs @@ -0,0 +1,19 @@ +#include "shared.rsh" + +const float floatTest = 1.99f; +const double doubleTest = 2.05; +const char charTest = -8; +const short shortTest = -16; +const int intTest = -32; +const long longTest = 17179869184l; // 1 << 34 +const long long longlongTest = 68719476736l; // 1 << 36 + +const uchar ucharTest = 8; +const ushort ushortTest = 16; +const uint uintTest = 32; +const ulong ulongTest = 4611686018427387904L; +const int64_t int64_tTest = -17179869184l; // - 1 << 34 +const uint64_t uint64_tTest = 117179869184l; + +const bool boolTest = true; + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs new file mode 100644 index 0000000..e314f2b --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs @@ -0,0 +1,37 @@ +#include "shared.rsh" + +float4 f4 = { 2.0f, 4.0f, 6.0f, 8.0f }; + +char4 i8_4 = { -1, -2, -3, 4 }; + +static bool test_convert() { + bool failed = false; + + f4 = convert_float4(i8_4); + _RS_ASSERT(f4.x == -1.0f); + _RS_ASSERT(f4.y == -2.0f); + _RS_ASSERT(f4.z == -3.0f); + _RS_ASSERT(f4.w == 4.0f); + + if (failed) { + rsDebug("test_convert FAILED", 0); + } + else { + rsDebug("test_convert PASSED", 0); + } + + return failed; +} + +void convert_test() { + bool failed = false; + failed |= test_convert(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs new file mode 100644 index 0000000..0c42d84 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs @@ -0,0 +1,158 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_element simpleElem; +rs_element complexElem; +typedef struct ComplexStruct { + float subElem0; + float subElem1; + int subElem2; + float arrayElem0[2]; + int arrayElem1[5]; + char subElem3; + float subElem4; + float2 subElem5; + float3 subElem6; + float4 subElem_7; +} ComplexStruct_t; + +ComplexStruct_t *complexStruct; + +static const char *subElemNames[] = { + "subElem0", + "subElem1", + "subElem2", + "arrayElem0", + "arrayElem1", + "subElem3", + "subElem4", + "subElem5", + "subElem6", + "subElem_7", +}; + +static uint32_t subElemNamesSizes[] = { + 8, + 8, + 8, + 10, + 10, + 8, + 8, + 8, + 8, + 9, +}; + +static uint32_t subElemArraySizes[] = { + 1, + 1, + 1, + 2, + 5, + 1, + 1, + 1, + 1, + 1, +}; + +static void resetStruct() { + uint8_t *bytePtr = (uint8_t*)complexStruct; + uint32_t sizeOfStruct = sizeof(*complexStruct); + for(uint32_t i = 0; i < sizeOfStruct; i ++) { + bytePtr[i] = 0; + } +} + +static bool equals(const char *name0, const char * name1, uint32_t len) { + for (uint32_t i = 0; i < len; i ++) { + if (name0[i] != name1[i]) { + return false; + } + } + return true; +} + +static bool test_element_getters() { + bool failed = false; + + uint32_t subElemOffsets[10]; + uint32_t index = 0; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem0 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem1 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem2 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem0 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem1 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem3 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem4 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem5 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem6 - (uint32_t)complexStruct; + subElemOffsets[index++] = (uint32_t)&complexStruct->subElem_7 - (uint32_t)complexStruct; + + uint32_t subElemCount = rsElementGetSubElementCount(simpleElem); + _RS_ASSERT(subElemCount == 0); + _RS_ASSERT(rsElementGetDataKind(simpleElem) == RS_KIND_USER); + _RS_ASSERT(rsElementGetDataType(simpleElem) == RS_TYPE_FLOAT_32); + _RS_ASSERT(rsElementGetVectorSize(simpleElem) == 3); + + subElemCount = rsElementGetSubElementCount(complexElem); + _RS_ASSERT(subElemCount == 10); + _RS_ASSERT(rsElementGetDataKind(complexElem) == RS_KIND_USER); + _RS_ASSERT(rsElementGetDataType(complexElem) == RS_TYPE_NONE); + _RS_ASSERT(rsElementGetVectorSize(complexElem) == 1); + _RS_ASSERT(rsElementGetSizeBytes(complexElem) == sizeof(*complexStruct)); + + char buffer[64]; + for (uint32_t i = 0; i < subElemCount; i ++) { + rs_element subElem = rsElementGetSubElement(complexElem, i); + _RS_ASSERT(rsIsObject(subElem)); + + _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, i) == subElemNamesSizes[i] + 1); + + uint32_t written = rsElementGetSubElementName(complexElem, i, buffer, 64); + _RS_ASSERT(written == subElemNamesSizes[i]); + _RS_ASSERT(equals(buffer, subElemNames[i], written)); + + _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, i) == subElemArraySizes[i]); + _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, i) == subElemOffsets[i]); + } + + // Tests error checking + rs_element subElem = rsElementGetSubElement(complexElem, subElemCount); + _RS_ASSERT(!rsIsObject(subElem)); + + _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, subElemCount) == 0); + + _RS_ASSERT(rsElementGetSubElementName(complexElem, subElemCount, buffer, 64) == 0); + _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, NULL, 64) == 0); + _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, buffer, 0) == 0); + uint32_t written = rsElementGetSubElementName(complexElem, 0, buffer, 5); + _RS_ASSERT(written == 4); + _RS_ASSERT(buffer[4] == '\0'); + + _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, subElemCount) == 0); + _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, subElemCount) == 0); + + if (failed) { + rsDebug("test_element_getters FAILED", 0); + } + else { + rsDebug("test_element_getters PASSED", 0); + } + + return failed; +} + +void element_test() { + bool failed = false; + failed |= test_element_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs index 3ba3eef..ac527b5 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs @@ -3,12 +3,19 @@ int *a; int dimX; int dimY; +static bool failed = false; void root(int *out, uint32_t x, uint32_t y) { *out = x + y * dimX; } -static bool test_foreach_output() { +void foo(const int *in, int *out, uint32_t x, uint32_t y) { + _RS_ASSERT(*in == (x + y * dimX)); + *out = 99 + x + y * dimX; + _RS_ASSERT(*out == (99 + x + y * dimX)); +} + +static bool test_root_output() { bool failed = false; int i, j; @@ -19,19 +26,44 @@ static bool test_foreach_output() { } if (failed) { - rsDebug("test_foreach_output FAILED", 0); + rsDebug("test_root_output FAILED", 0); } else { - rsDebug("test_foreach_output PASSED", 0); + rsDebug("test_root_output PASSED", 0); } return failed; } -void foreach_test() { +static bool test_foo_output() { bool failed = false; - failed |= test_foreach_output(); + int i, j; + + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX)); + } + } + + if (failed) { + rsDebug("test_foo_output FAILED", 0); + } + else { + rsDebug("test_foo_output PASSED", 0); + } + + return failed; +} +void verify_root() { + failed |= test_root_output(); +} + +void verify_foo() { + failed |= test_foo_output(); +} + +void foreach_test() { if (failed) { rsSendToClientBlocking(RS_MSG_TEST_FAILED); } diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs new file mode 100644 index 0000000..1354897 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs @@ -0,0 +1,64 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_mesh mesh; +rs_allocation vertexAlloc0; +rs_allocation vertexAlloc1; + +rs_allocation indexAlloc0; +rs_allocation indexAlloc2; + +static bool test_mesh_getters() { + bool failed = false; + + _RS_ASSERT(rsgMeshGetVertexAllocationCount(mesh) == 2); + _RS_ASSERT(rsgMeshGetPrimitiveCount(mesh) == 3); + + rs_allocation meshV0 = rsgMeshGetVertexAllocation(mesh, 0); + rs_allocation meshV1 = rsgMeshGetVertexAllocation(mesh, 1); + rs_allocation meshV2 = rsgMeshGetVertexAllocation(mesh, 2); + _RS_ASSERT(meshV0.p == vertexAlloc0.p); + _RS_ASSERT(meshV1.p == vertexAlloc1.p); + _RS_ASSERT(!rsIsObject(meshV2)); + + rs_allocation meshI0 = rsgMeshGetIndexAllocation(mesh, 0); + rs_allocation meshI1 = rsgMeshGetIndexAllocation(mesh, 1); + rs_allocation meshI2 = rsgMeshGetIndexAllocation(mesh, 2); + rs_allocation meshI3 = rsgMeshGetIndexAllocation(mesh, 3); + _RS_ASSERT(meshI0.p == indexAlloc0.p); + _RS_ASSERT(!rsIsObject(meshI1)); + _RS_ASSERT(meshI2.p == indexAlloc2.p); + _RS_ASSERT(!rsIsObject(meshI3)); + + rs_primitive p0 = rsgMeshGetPrimitive(mesh, 0); + rs_primitive p1 = rsgMeshGetPrimitive(mesh, 1); + rs_primitive p2 = rsgMeshGetPrimitive(mesh, 2); + rs_primitive p3 = rsgMeshGetPrimitive(mesh, 3); + + _RS_ASSERT(p0 == RS_PRIMITIVE_POINT); + _RS_ASSERT(p1 == RS_PRIMITIVE_LINE); + _RS_ASSERT(p2 == RS_PRIMITIVE_TRIANGLE); + _RS_ASSERT(p3 == RS_PRIMITIVE_INVALID); + + if (failed) { + rsDebug("test_mesh_getters FAILED", 0); + } + else { + rsDebug("test_mesh_getters PASSED", 0); + } + + return failed; +} + +void mesh_test() { + bool failed = false; + failed |= test_mesh_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs new file mode 100644 index 0000000..33944aa --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs @@ -0,0 +1,44 @@ +#include "shared.rsh" + +int *a; +int dimX; +int dimY; +static bool failed = false; + +void foo(const int *in, int *out, uint32_t x, uint32_t y) { + *out = 99 + x + y * dimX; +} + +static bool test_foo_output() { + bool failed = false; + int i, j; + + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + _RS_ASSERT(a[i + j * dimX] == (99 + i + j * dimX)); + } + } + + if (failed) { + rsDebug("test_foo_output FAILED", 0); + } + else { + rsDebug("test_foo_output PASSED", 0); + } + + return failed; +} + +void verify_foo() { + failed |= test_foo_output(); +} + +void noroot_test() { + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs new file mode 100644 index 0000000..11b8c30 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs @@ -0,0 +1,37 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_program_raster pointSpriteEnabled; +rs_program_raster cullMode; + +static bool test_program_raster_getters() { + bool failed = false; + + _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(pointSpriteEnabled) == true); + _RS_ASSERT(rsgProgramRasterGetCullMode(pointSpriteEnabled) == RS_CULL_BACK); + + _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(cullMode) == false); + _RS_ASSERT(rsgProgramRasterGetCullMode(cullMode) == RS_CULL_FRONT); + + if (failed) { + rsDebug("test_program_raster_getters FAILED", 0); + } + else { + rsDebug("test_program_raster_getters PASSED", 0); + } + + return failed; +} + +void program_raster_test() { + bool failed = false; + failed |= test_program_raster_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs new file mode 100644 index 0000000..3cd8a20 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs @@ -0,0 +1,128 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_program_store ditherEnable; +rs_program_store colorRWriteEnable; +rs_program_store colorGWriteEnable; +rs_program_store colorBWriteEnable; +rs_program_store colorAWriteEnable; +rs_program_store blendSrc; +rs_program_store blendDst; +rs_program_store depthWriteEnable; +rs_program_store depthFunc; + +static bool test_program_store_getters() { + bool failed = false; + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthFunc) == RS_DEPTH_FUNC_GREATER); + _RS_ASSERT(rsgProgramStoreGetDepthMask(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthFunc) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthFunc) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthFunc) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthWriteEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(depthWriteEnable) == true); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthWriteEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthWriteEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorRWriteEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(colorRWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorRWriteEnable) == true); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorRWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorRWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorRWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorRWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorRWriteEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorRWriteEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorGWriteEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(colorGWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorGWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorGWriteEnable) == true); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorGWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorGWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorGWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorGWriteEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorGWriteEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorBWriteEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(colorBWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorBWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorBWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorBWriteEnable) == true); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorBWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorBWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorBWriteEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorBWriteEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorAWriteEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(colorAWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorAWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorAWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorAWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorAWriteEnable) == true); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorAWriteEnable) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorAWriteEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorAWriteEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(ditherEnable) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(ditherEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(ditherEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(ditherEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(ditherEnable) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(ditherEnable) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(ditherEnable) == true); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(ditherEnable) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(ditherEnable) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendSrc) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendSrc) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendSrc) == RS_BLEND_SRC_DST_COLOR); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendSrc) == RS_BLEND_DST_ZERO); + + _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendDst) == RS_DEPTH_FUNC_ALWAYS); + _RS_ASSERT(rsgProgramStoreGetDepthMask(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendDst) == false); + _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendDst) == RS_BLEND_SRC_ZERO); + _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendDst) == RS_BLEND_DST_DST_ALPHA); + + if (failed) { + rsDebug("test_program_store_getters FAILED", 0); + } + else { + rsDebug("test_program_store_getters PASSED", 0); + } + + return failed; +} + +void program_store_test() { + bool failed = false; + failed |= test_program_store_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs index 5e3e078..7be955d 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs @@ -19,7 +19,7 @@ static bool basic_test(uint32_t index) { rsDebug("tm.tm_yday", tm.tm_yday); rsDebug("tm.tm_isdst", tm.tm_isdst); - // Test a specific time (only valid for PST localtime) + // Test a specific time (since we set America/Los_Angeles localtime) curTime = 1294438893; rsLocaltime(&tm, &curTime); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs new file mode 100644 index 0000000..ff1c0a7 --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs @@ -0,0 +1,63 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" +rs_sampler minification; +rs_sampler magnification; +rs_sampler wrapS; +rs_sampler wrapT; +rs_sampler anisotropy; + +static bool test_sampler_getters() { + bool failed = false; + + _RS_ASSERT(rsSamplerGetMagnification(minification) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetMinification(minification) == RS_SAMPLER_LINEAR_MIP_LINEAR); + _RS_ASSERT(rsSamplerGetWrapS(minification) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetWrapT(minification) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetAnisotropy(minification) == 1.0f); + + _RS_ASSERT(rsSamplerGetMagnification(magnification) == RS_SAMPLER_LINEAR); + _RS_ASSERT(rsSamplerGetMinification(magnification) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetWrapS(magnification) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetWrapT(magnification) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetAnisotropy(magnification) == 1.0f); + + _RS_ASSERT(rsSamplerGetMagnification(wrapS) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetMinification(wrapS) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetWrapS(wrapS) == RS_SAMPLER_WRAP); + _RS_ASSERT(rsSamplerGetWrapT(wrapS) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetAnisotropy(wrapS) == 1.0f); + + _RS_ASSERT(rsSamplerGetMagnification(wrapT) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetMinification(wrapT) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetWrapS(wrapT) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetWrapT(wrapT) == RS_SAMPLER_WRAP); + _RS_ASSERT(rsSamplerGetAnisotropy(wrapT) == 1.0f); + + _RS_ASSERT(rsSamplerGetMagnification(anisotropy) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetMinification(anisotropy) == RS_SAMPLER_NEAREST); + _RS_ASSERT(rsSamplerGetWrapS(anisotropy) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetWrapT(anisotropy) == RS_SAMPLER_CLAMP); + _RS_ASSERT(rsSamplerGetAnisotropy(anisotropy) == 8.0f); + + if (failed) { + rsDebug("test_sampler_getters FAILED", 0); + } + else { + rsDebug("test_sampler_getters PASSED", 0); + } + + return failed; +} + +void sampler_test() { + bool failed = false; + failed |= test_sampler_getters(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs new file mode 100644 index 0000000..1cd728e --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs @@ -0,0 +1,37 @@ +#include "shared.rsh" + +typedef struct Point2 { + int x; + int y; +} Point_2; +Point_2 *point2; + +static bool test_Point_2(int expected) { + bool failed = false; + + rsDebug("Point: ", point2[0].x, point2[0].y); + _RS_ASSERT(point2[0].x == expected); + _RS_ASSERT(point2[0].y == expected); + + if (failed) { + rsDebug("test_Point_2 FAILED", 0); + } + else { + rsDebug("test_Point_2 PASSED", 0); + } + + return failed; +} + +void struct_test(int expected) { + bool failed = false; + failed |= test_Point_2(expected); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/Android.mk b/tests/RenderScriptTests/tests_v11/Android.mk new file mode 100644 index 0000000..93a429b --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/Android.mk @@ -0,0 +1,31 @@ +# +# 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. +# + +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := RSTest_v11 +LOCAL_SDK_VERSION := 11 + +include $(BUILD_PACKAGE) + +endif diff --git a/tests/RenderScriptTests/tests_v11/AndroidManifest.xml b/tests/RenderScriptTests/tests_v11/AndroidManifest.xml new file mode 100644 index 0000000..f4aeda2 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/AndroidManifest.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rs.test_v11"> + <uses-sdk android:minSdkVersion="11" /> + <application + android:label="_RS_Test_v11" + android:icon="@drawable/test_pattern"> + <activity android:name="RSTest_v11" + android:screenOrientation="portrait"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/tests_v11/res/drawable/test_pattern.png b/tests/RenderScriptTests/tests_v11/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/res/drawable/test_pattern.png diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestCore.java new file mode 100644 index 0000000..888cfe4 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestCore.java @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.Timer; +import java.util.TimerTask; + + +public class RSTestCore { + int mWidth; + int mHeight; + Context mCtx; + + public RSTestCore(Context ctx) { + mCtx = ctx; + } + + private Resources mRes; + private RenderScriptGL mRS; + + private Font mFont; + ScriptField_ListAllocs_s mListAllocs; + int mLastX; + int mLastY; + private ScriptC_rslist mScript; + + private ArrayList<UnitTest> unitTests; + private ListIterator<UnitTest> test_iter; + private UnitTest activeTest; + private boolean stopTesting; + + /* Periodic timer for ensuring future tests get scheduled */ + private Timer mTimer; + public static final int RS_TIMER_PERIOD = 100; + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + stopTesting = false; + + mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist); + + unitTests = new ArrayList<UnitTest>(); + + unitTests.add(new UT_primitives(this, mRes, mCtx)); + unitTests.add(new UT_rsdebug(this, mRes, mCtx)); + unitTests.add(new UT_rstime(this, mRes, mCtx)); + unitTests.add(new UT_rstypes(this, mRes, mCtx)); + unitTests.add(new UT_math(this, mRes, mCtx)); + unitTests.add(new UT_fp_mad(this, mRes, mCtx)); + /* + unitTests.add(new UnitTest(null, "<Pass>", 1)); + unitTests.add(new UnitTest()); + unitTests.add(new UnitTest(null, "<Fail>", -1)); + + for (int i = 0; i < 20; i++) { + unitTests.add(new UnitTest(null, "<Pass>", 1)); + } + */ + + UnitTest [] uta = new UnitTest[unitTests.size()]; + uta = unitTests.toArray(uta); + + mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length); + for (int i = 0; i < uta.length; i++) { + ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item(); + listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT); + listElem.result = uta[i].result; + mListAllocs.set(listElem, i, false); + uta[i].setItem(listElem); + } + + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + + mFont = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8); + mScript.set_gFont(mFont); + + mRS.bindRootScript(mScript); + + test_iter = unitTests.listIterator(); + refreshTestResults(); /* Kick off the first test */ + + TimerTask pTask = new TimerTask() { + public void run() { + refreshTestResults(); + } + }; + + mTimer = new Timer(); + mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD); + } + + public void checkAndRunNextTest() { + if (activeTest != null) { + if (!activeTest.isAlive()) { + /* Properly clean up on our last test */ + try { + activeTest.join(); + } + catch (InterruptedException e) { + } + activeTest = null; + } + } + + if (!stopTesting && activeTest == null) { + if (test_iter.hasNext()) { + activeTest = test_iter.next(); + activeTest.start(); + /* This routine will only get called once when a new test + * should start running. The message handler in UnitTest.java + * ensures this. */ + } + else { + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + } + } + } + + public void refreshTestResults() { + checkAndRunNextTest(); + + if (mListAllocs != null && mScript != null && mRS != null) { + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + mRS.bindRootScript(mScript); + } + } + + public void cleanup() { + stopTesting = true; + UnitTest t = activeTest; + + /* Stop periodic refresh of testing */ + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + + /* Wait to exit until we finish the current test */ + if (t != null) { + try { + t.join(); + } + catch (InterruptedException e) { + } + t = null; + } + + } + + public void newTouchPosition(float x, float y, float pressure, int id) { + } + + public void onActionDown(int x, int y) { + mScript.set_gDY(0.0f); + mLastX = x; + mLastY = y; + refreshTestResults(); + } + + public void onActionMove(int x, int y) { + int dx = mLastX - x; + int dy = mLastY - y; + + if (Math.abs(dy) <= 2) { + dy = 0; + } + + mScript.set_gDY(dy); + + mLastX = x; + mLastY = y; + refreshTestResults(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestView.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestView.java new file mode 100644 index 0000000..b5bebe9 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestView.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v11; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RSTestView extends RSSurfaceView { + + private Context mCtx; + + public RSTestView(Context context) { + super(context); + mCtx = context; + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RSTestCore mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new RSTestCore(mCtx); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRender.cleanup(); + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + else if (act == ev.ACTION_MOVE) { + mRender.onActionMove((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTest_v11.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTest_v11.java new file mode 100644 index 0000000..1dedfce --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTest_v11.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v11; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class RSTest_v11 extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "libRS_jni"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; + + private RSTestView mView; + + // get the current looper (from your Activity UI thread for instance + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new RSTestView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onPause(); + mView.pause(); + } + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_fp_mad.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_fp_mad.java new file mode 100644 index 0000000..5d72aa6 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_fp_mad.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_fp_mad extends UnitTest { + private Resources mRes; + + protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Fp_Mad", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad); + pRS.setMessageHandler(mRsMessage); + s.invoke_fp_mad_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_math.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_math.java new file mode 100644 index 0000000..7e356f8 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_math.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_math extends UnitTest { + private Resources mRes; + + protected UT_math(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Math", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_math s = new ScriptC_math(pRS, mRes, R.raw.math); + pRS.setMessageHandler(mRsMessage); + s.invoke_math_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_primitives.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_primitives.java new file mode 100644 index 0000000..dc3efbc --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_primitives.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_primitives extends UnitTest { + private Resources mRes; + + protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Primitives", ctx); + mRes = res; + } + + private boolean initializeGlobals(ScriptC_primitives s) { + float pF = s.get_floatTest(); + if (pF != 1.99f) { + return false; + } + s.set_floatTest(2.99f); + + double pD = s.get_doubleTest(); + if (pD != 2.05) { + return false; + } + s.set_doubleTest(3.05); + + byte pC = s.get_charTest(); + if (pC != -8) { + return false; + } + s.set_charTest((byte)-16); + + short pS = s.get_shortTest(); + if (pS != -16) { + return false; + } + s.set_shortTest((short)-32); + + int pI = s.get_intTest(); + if (pI != -32) { + return false; + } + s.set_intTest(-64); + + long pL = s.get_longTest(); + if (pL != 17179869184l) { + return false; + } + s.set_longTest(17179869185l); + + long puL = s.get_ulongTest(); + if (puL != 4611686018427387904L) { + return false; + } + s.set_ulongTest(4611686018427387903L); + + + long pLL = s.get_longlongTest(); + if (pLL != 68719476736L) { + return false; + } + s.set_longlongTest(68719476735L); + + long pu64 = s.get_uint64_tTest(); + if (pu64 != 117179869184l) { + return false; + } + s.set_uint64_tTest(117179869185l); + + return true; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives); + pRS.setMessageHandler(mRsMessage); + if (!initializeGlobals(s)) { + // initializeGlobals failed + result = -1; + } else { + s.invoke_primitives_test(0, 0); + pRS.finish(); + waitForMessage(); + } + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rsdebug.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rsdebug.java new file mode 100644 index 0000000..00dbaf5 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rsdebug.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rsdebug extends UnitTest { + private Resources mRes; + + protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsDebug", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rsdebug(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstime.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstime.java new file mode 100644 index 0000000..5b4c399 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstime.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rstime extends UnitTest { + private Resources mRes; + + protected UT_rstime(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsTime", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rstime s = new ScriptC_rstime(pRS, mRes, R.raw.rstime); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rstime(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstypes.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstypes.java new file mode 100644 index 0000000..72a97c9 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstypes.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v11; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rstypes extends UnitTest { + private Resources mRes; + + protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsTypes", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rstypes s = new ScriptC_rstypes(pRS, mRes, R.raw.rstypes); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rstypes(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UnitTest.java new file mode 100644 index 0000000..b62e535 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UnitTest.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010 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.test_v11; +import android.content.Context; +import android.renderscript.RenderScript.RSMessageHandler; +import android.util.Log; + +public class UnitTest extends Thread { + public String name; + public int result; + private ScriptField_ListAllocs_s.Item mItem; + private RSTestCore mRSTC; + private boolean msgHandled; + protected Context mCtx; + + /* These constants must match those in shared.rsh */ + public static final int RS_MSG_TEST_PASSED = 100; + public static final int RS_MSG_TEST_FAILED = 101; + + private static int numTests = 0; + public int testID; + + protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) { + super(); + mRSTC = rstc; + name = n; + msgHandled = false; + mCtx = ctx; + result = initResult; + testID = numTests++; + } + + protected UnitTest(RSTestCore rstc, String n, Context ctx) { + this(rstc, n, 0, ctx); + } + + protected UnitTest(RSTestCore rstc, Context ctx) { + this (rstc, "<Unknown>", ctx); + } + + protected UnitTest(Context ctx) { + this (null, ctx); + } + + protected RSMessageHandler mRsMessage = new RSMessageHandler() { + public void run() { + if (result == 0) { + switch (mID) { + case RS_MSG_TEST_PASSED: + result = 1; + break; + case RS_MSG_TEST_FAILED: + result = -1; + break; + default: + android.util.Log.v("RenderScript", "Unit test got unexpected message"); + return; + } + } + + if (mItem != null) { + mItem.result = result; + msgHandled = true; + try { + mRSTC.refreshTestResults(); + } + catch (IllegalStateException e) { + /* Ignore the case where our message receiver has been + disconnected. This happens when we leave the application + before it finishes running all of the unit tests. */ + } + } + } + }; + + public void waitForMessage() { + while (!msgHandled) { + yield(); + } + } + + public void setItem(ScriptField_ListAllocs_s.Item item) { + mItem = item; + } + + public void run() { + /* This method needs to be implemented for each subclass */ + if (mRSTC != null) { + mRSTC.refreshTestResults(); + } + } +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/fp_mad.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/fp_mad.rs new file mode 100644 index 0000000..b6f2b2a --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/fp_mad.rs @@ -0,0 +1,174 @@ +#include "shared.rsh" + +const int TEST_COUNT = 1; + +static float data_f1[1025]; +static float4 data_f4[1025]; + +static void test_mad4(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 80); ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = (data_f4[i] * 0.02f + + data_f4[i+1] * 0.04f + + data_f4[i+2] * 0.05f + + data_f4[i+3] * 0.1f + + data_f4[i+4] * 0.2f + + data_f4[i+5] * 0.2f + + data_f4[i+6] * 0.1f + + data_f4[i+7] * 0.05f + + data_f4[i+8] * 0.04f + + data_f4[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad4 M ops", 1000.f / time); +} + +static void test_mad(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 20); ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = (data_f1[i] * 0.02f + + data_f1[i+1] * 0.04f + + data_f1[i+2] * 0.05f + + data_f1[i+3] * 0.1f + + data_f1[i+4] * 0.2f + + data_f1[i+5] * 0.2f + + data_f1[i+6] * 0.1f + + data_f1[i+7] * 0.05f + + data_f1[i+8] * 0.04f + + data_f1[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad M ops", 1000.f / time); +} + +static void test_norm(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = normalize(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_norm M ops", 10.f / time); +} + +static void test_sincos4(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10 / 4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = sin(data_f4[i]) * cos(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos4 M ops", 10.f / time); +} + +static void test_sincos(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = sin(data_f1[i]) * cos(data_f1[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos M ops", 10.f / time); +} + +static void test_clamp(uint32_t index) { + start(); + + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = clamp(data_f1[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp M ops", 100.f / time); + + start(); + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + if (data_f1[i] < -1.f) data_f1[i] = -1.f; + if (data_f1[i] > -1.f) data_f1[i] = 1.f; + } + } + + time = end(index); + rsDebug("fp_clamp ref M ops", 100.f / time); +} + +static void test_clamp4(uint32_t index) { + start(); + + float total = 0; + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100 /4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = clamp(data_f4[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp4 M ops", 100.f / time); +} + +void fp_mad_test(uint32_t index, int test_num) { + int x; + for (x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f; + data_f4[x].x = (x & 0xf) * 0.1f; + data_f4[x].y = (x & 0xf0) * 0.1f; + data_f4[x].z = (x & 0x33) * 0.1f; + data_f4[x].w = (x & 0x77) * 0.1f; + } + + test_mad4(index); + test_mad(index); + + for (x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f + 1.f; + data_f4[x].x = (x & 0xf) * 0.1f + 1.f; + data_f4[x].y = (x & 0xf0) * 0.1f + 1.f; + data_f4[x].z = (x & 0x33) * 0.1f + 1.f; + data_f4[x].w = (x & 0x77) * 0.1f + 1.f; + } + + test_norm(index); + test_sincos4(index); + test_sincos(index); + test_clamp4(index); + test_clamp(index); + + // TODO Actually verify test result accuracy + rsDebug("fp_mad_test PASSED", 0); + rsSendToClientBlocking(RS_MSG_TEST_PASSED); +} + + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/math.rs new file mode 100644 index 0000000..2867be1 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/math.rs @@ -0,0 +1,348 @@ +#include "shared.rsh" + +// Testing math library + +volatile float f1; +volatile float2 f2; +volatile float3 f3; +volatile float4 f4; + +volatile int i1; +volatile int2 i2; +volatile int3 i3; +volatile int4 i4; + +volatile uint ui1; +volatile uint2 ui2; +volatile uint3 ui3; +volatile uint4 ui4; + +volatile short s1; +volatile short2 s2; +volatile short3 s3; +volatile short4 s4; + +volatile ushort us1; +volatile ushort2 us2; +volatile ushort3 us3; +volatile ushort4 us4; + +volatile char c1; +volatile char2 c2; +volatile char3 c3; +volatile char4 c4; + +volatile uchar uc1; +volatile uchar2 uc2; +volatile uchar3 uc3; +volatile uchar4 uc4; + +#define TEST_FN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f2 = fnc(f2); \ + f3 = fnc(f3); \ + f4 = fnc(f4); + +#define TEST_FN_FUNC_FN_PFN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (float*) &f1); \ + f2 = fnc(f2, (float2*) &f2); \ + f3 = fnc(f3, (float3*) &f3); \ + f4 = fnc(f4, (float4*) &f4); + +#define TEST_FN_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f2); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f1); \ + f3 = fnc(f3, f1); \ + f4 = fnc(f4, f1); + +#define TEST_FN_FUNC_FN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i2); \ + f3 = fnc(f3, i3); \ + f4 = fnc(f4, i4); + +#define TEST_FN_FUNC_FN_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i1); \ + f3 = fnc(f3, i1); \ + f4 = fnc(f4, i1); + +#define TEST_FN_FUNC_FN_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f2, f2); \ + f3 = fnc(f3, f3, f3); \ + f4 = fnc(f4, f4, f4); + +#define TEST_FN_FUNC_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (int*) &i1); \ + f2 = fnc(f2, (int2*) &i2); \ + f3 = fnc(f3, (int3*) &i3); \ + f4 = fnc(f4, (int4*) &i4); + +#define TEST_FN_FUNC_FN_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, (int*) &i1); \ + f2 = fnc(f2, f2, (int2*) &i2); \ + f3 = fnc(f3, f3, (int3*) &i3); \ + f4 = fnc(f4, f4, (int4*) &i4); + +#define TEST_IN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + i1 = fnc(f1); \ + i2 = fnc(f2); \ + i3 = fnc(f3); \ + i4 = fnc(f4); + + +static bool test_fp_math(uint32_t index) { + bool failed = false; + start(); + + TEST_FN_FUNC_FN(acos); + TEST_FN_FUNC_FN(acosh); + TEST_FN_FUNC_FN(acospi); + TEST_FN_FUNC_FN(asin); + TEST_FN_FUNC_FN(asinh); + TEST_FN_FUNC_FN(asinpi); + TEST_FN_FUNC_FN(atan); + TEST_FN_FUNC_FN_FN(atan2); + TEST_FN_FUNC_FN(atanh); + TEST_FN_FUNC_FN(atanpi); + TEST_FN_FUNC_FN_FN(atan2pi); + TEST_FN_FUNC_FN(cbrt); + TEST_FN_FUNC_FN(ceil); + TEST_FN_FUNC_FN_FN(copysign); + TEST_FN_FUNC_FN(cos); + TEST_FN_FUNC_FN(cosh); + TEST_FN_FUNC_FN(cospi); + TEST_FN_FUNC_FN(erfc); + TEST_FN_FUNC_FN(erf); + TEST_FN_FUNC_FN(exp); + TEST_FN_FUNC_FN(exp2); + TEST_FN_FUNC_FN(exp10); + TEST_FN_FUNC_FN(expm1); + TEST_FN_FUNC_FN(fabs); + TEST_FN_FUNC_FN_FN(fdim); + TEST_FN_FUNC_FN(floor); + TEST_FN_FUNC_FN_FN_FN(fma); + TEST_FN_FUNC_FN_FN(fmax); + TEST_FN_FUNC_FN_F(fmax); + TEST_FN_FUNC_FN_FN(fmin); + TEST_FN_FUNC_FN_F(fmin); + TEST_FN_FUNC_FN_FN(fmod); + TEST_FN_FUNC_FN_PFN(fract); + TEST_FN_FUNC_FN_PIN(frexp); + TEST_FN_FUNC_FN_FN(hypot); + TEST_IN_FUNC_FN(ilogb); + TEST_FN_FUNC_FN_IN(ldexp); + TEST_FN_FUNC_FN_I(ldexp); + TEST_FN_FUNC_FN(lgamma); + TEST_FN_FUNC_FN_PIN(lgamma); + TEST_FN_FUNC_FN(log); + TEST_FN_FUNC_FN(log2); + TEST_FN_FUNC_FN(log10); + TEST_FN_FUNC_FN(log1p); + TEST_FN_FUNC_FN(logb); + TEST_FN_FUNC_FN_FN_FN(mad); + TEST_FN_FUNC_FN_PFN(modf); + // nan + TEST_FN_FUNC_FN_FN(nextafter); + TEST_FN_FUNC_FN_FN(pow); + TEST_FN_FUNC_FN_IN(pown); + TEST_FN_FUNC_FN_FN(powr); + TEST_FN_FUNC_FN_FN(remainder); + TEST_FN_FUNC_FN_FN_PIN(remquo); + TEST_FN_FUNC_FN(rint); + TEST_FN_FUNC_FN_IN(rootn); + TEST_FN_FUNC_FN(round); + TEST_FN_FUNC_FN(rsqrt); + TEST_FN_FUNC_FN(sin); + TEST_FN_FUNC_FN_PFN(sincos); + TEST_FN_FUNC_FN(sinh); + TEST_FN_FUNC_FN(sinpi); + TEST_FN_FUNC_FN(sqrt); + TEST_FN_FUNC_FN(tan); + TEST_FN_FUNC_FN(tanh); + TEST_FN_FUNC_FN(tanpi); + TEST_FN_FUNC_FN(tgamma); + TEST_FN_FUNC_FN(trunc); + + float time = end(index); + + if (failed) { + rsDebug("test_fp_math FAILED", time); + } + else { + rsDebug("test_fp_math PASSED", time); + } + + return failed; +} + +#define DECL_INT(prefix) \ +volatile char prefix##_c_1 = 1; \ +volatile char2 prefix##_c_2 = 1; \ +volatile char3 prefix##_c_3 = 1; \ +volatile char4 prefix##_c_4 = 1; \ +volatile uchar prefix##_uc_1 = 1; \ +volatile uchar2 prefix##_uc_2 = 1; \ +volatile uchar3 prefix##_uc_3 = 1; \ +volatile uchar4 prefix##_uc_4 = 1; \ +volatile short prefix##_s_1 = 1; \ +volatile short2 prefix##_s_2 = 1; \ +volatile short3 prefix##_s_3 = 1; \ +volatile short4 prefix##_s_4 = 1; \ +volatile ushort prefix##_us_1 = 1; \ +volatile ushort2 prefix##_us_2 = 1; \ +volatile ushort3 prefix##_us_3 = 1; \ +volatile ushort4 prefix##_us_4 = 1; \ +volatile int prefix##_i_1 = 1; \ +volatile int2 prefix##_i_2 = 1; \ +volatile int3 prefix##_i_3 = 1; \ +volatile int4 prefix##_i_4 = 1; \ +volatile uint prefix##_ui_1 = 1; \ +volatile uint2 prefix##_ui_2 = 1; \ +volatile uint3 prefix##_ui_3 = 1; \ +volatile uint4 prefix##_ui_4 = 1; \ +volatile long prefix##_l_1 = 1; \ +volatile ulong prefix##_ul_1 = 1; + +#define TEST_INT_OP_TYPE(op, type) \ +rsDebug("Testing " #op " for " #type "1", i++); \ +res_##type##_1 = src1_##type##_1 op src2_##type##_1; \ +rsDebug("Testing " #op " for " #type "2", i++); \ +res_##type##_2 = src1_##type##_2 op src2_##type##_2; \ +rsDebug("Testing " #op " for " #type "3", i++); \ +res_##type##_3 = src1_##type##_3 op src2_##type##_3; \ +rsDebug("Testing " #op " for " #type "4", i++); \ +res_##type##_4 = src1_##type##_4 op src2_##type##_4; + +#define TEST_INT_OP(op) \ +TEST_INT_OP_TYPE(op, c) \ +TEST_INT_OP_TYPE(op, uc) \ +TEST_INT_OP_TYPE(op, s) \ +TEST_INT_OP_TYPE(op, us) \ +TEST_INT_OP_TYPE(op, i) \ +TEST_INT_OP_TYPE(op, ui) \ +rsDebug("Testing " #op " for l1", i++); \ +res_l_1 = src1_l_1 op src2_l_1; \ +rsDebug("Testing " #op " for ul1", i++); \ +res_ul_1 = src1_ul_1 op src2_ul_1; + +DECL_INT(res) +DECL_INT(src1) +DECL_INT(src2) + +static bool test_basic_operators() { + bool failed = false; + int i = 0; + + TEST_INT_OP(+); + TEST_INT_OP(-); + TEST_INT_OP(*); + TEST_INT_OP(/); + TEST_INT_OP(%); + TEST_INT_OP(<<); + TEST_INT_OP(>>); + + if (failed) { + rsDebug("test_basic_operators FAILED", 0); + } + else { + rsDebug("test_basic_operators PASSED", 0); + } + + return failed; +} + +#define TEST_CVT(to, from, type) \ +rsDebug("Testing convert from " #from " to " #to, 0); \ +to##1 = from##1; \ +to##2 = convert_##type##2(from##2); \ +to##3 = convert_##type##3(from##3); \ +to##4 = convert_##type##4(from##4); + +#define TEST_CVT_MATRIX(to, type) \ +TEST_CVT(to, c, type); \ +TEST_CVT(to, uc, type); \ +TEST_CVT(to, s, type); \ +TEST_CVT(to, us, type); \ +TEST_CVT(to, i, type); \ +TEST_CVT(to, ui, type); \ +TEST_CVT(to, f, type); \ + +static bool test_convert() { + bool failed = false; + + TEST_CVT_MATRIX(c, char); + TEST_CVT_MATRIX(uc, uchar); + TEST_CVT_MATRIX(s, short); + TEST_CVT_MATRIX(us, ushort); + TEST_CVT_MATRIX(i, int); + TEST_CVT_MATRIX(ui, uint); + TEST_CVT_MATRIX(f, float); + + if (failed) { + rsDebug("test_convert FAILED", 0); + } + else { + rsDebug("test_convert PASSED", 0); + } + + return failed; +} + +#define INIT_PREFIX_TYPE(prefix, type) \ +prefix##_##type##_1 = 1; \ +prefix##_##type##_2.x = 1; \ +prefix##_##type##_2.y = 1; \ +prefix##_##type##_3.x = 1; \ +prefix##_##type##_3.y = 1; \ +prefix##_##type##_3.z = 1; \ +prefix##_##type##_4.x = 1; \ +prefix##_##type##_4.y = 1; \ +prefix##_##type##_4.z = 1; \ +prefix##_##type##_4.w = 1; + +#define INIT_TYPE(type) \ +INIT_PREFIX_TYPE(src1, type) \ +INIT_PREFIX_TYPE(src2, type) \ +INIT_PREFIX_TYPE(res, type) + +#define INIT_ALL \ +INIT_TYPE(c); \ +INIT_TYPE(uc); \ +INIT_TYPE(s); \ +INIT_TYPE(us); \ +INIT_TYPE(i); \ +INIT_TYPE(ui); + +void math_test(uint32_t index, int test_num) { + bool failed = false; + INIT_ALL; + failed |= test_convert(); + failed |= test_fp_math(index); + failed |= test_basic_operators(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/primitives.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/primitives.rs new file mode 100644 index 0000000..ce451da --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/primitives.rs @@ -0,0 +1,61 @@ +#include "shared.rsh" + +// Testing primitive types +float floatTest = 1.99f; +double doubleTest = 2.05; +char charTest = -8; +short shortTest = -16; +int intTest = -32; +long longTest = 17179869184l; // 1 << 34 +long long longlongTest = 68719476736l; // 1 << 36 + +uchar ucharTest = 8; +ushort ushortTest = 16; +uint uintTest = 32; +ulong ulongTest = 4611686018427387904L; +int64_t int64_tTest = -17179869184l; // - 1 << 34 +uint64_t uint64_tTest = 117179869184l; + +static bool test_primitive_types(uint32_t index) { + bool failed = false; + start(); + + _RS_ASSERT(floatTest == 2.99f); + _RS_ASSERT(doubleTest == 3.05); + _RS_ASSERT(charTest == -16); + _RS_ASSERT(shortTest == -32); + _RS_ASSERT(intTest == -64); + _RS_ASSERT(longTest == 17179869185l); + _RS_ASSERT(longlongTest == 68719476735l); + + _RS_ASSERT(ucharTest == 8); + _RS_ASSERT(ushortTest == 16); + _RS_ASSERT(uintTest == 32); + _RS_ASSERT(ulongTest == 4611686018427387903L); + _RS_ASSERT(int64_tTest == -17179869184l); + _RS_ASSERT(uint64_tTest == 117179869185l); + + float time = end(index); + + if (failed) { + rsDebug("test_primitives FAILED", time); + } + else { + rsDebug("test_primitives PASSED", time); + } + + return failed; +} + +void primitives_test(uint32_t index, int test_num) { + bool failed = false; + failed |= test_primitive_types(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rsdebug.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rsdebug.rs new file mode 100644 index 0000000..f7942a5 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rsdebug.rs @@ -0,0 +1,56 @@ +#include "shared.rsh" + +// Testing primitive types +float floatTest = 1.99f; +double doubleTest = 2.05; +char charTest = -8; +short shortTest = -16; +int intTest = -32; +long longTest = 17179869184l; // 1 << 34 +long long longlongTest = 68719476736l; // 1 << 36 + +uchar ucharTest = 8; +ushort ushortTest = 16; +uint uintTest = 32; +ulong ulongTest = 4611686018427387904L; +int64_t int64_tTest = -17179869184l; // - 1 << 34 +uint64_t uint64_tTest = 117179869184l; + +static bool basic_test(uint32_t index) { + bool failed = false; + + // This test focuses primarily on compilation-time, not run-time. + // For this reason, none of the outputs are actually checked. + + rsDebug("floatTest", floatTest); + rsDebug("doubleTest", doubleTest); + rsDebug("charTest", charTest); + rsDebug("shortTest", shortTest); + rsDebug("intTest", intTest); + rsDebug("longTest", longTest); + rsDebug("longlongTest", longlongTest); + + rsDebug("ucharTest", ucharTest); + rsDebug("ushortTest", ushortTest); + rsDebug("uintTest", uintTest); + rsDebug("ulongTest", ulongTest); + rsDebug("int64_tTest", int64_tTest); + rsDebug("uint64_tTest", uint64_tTest); + + return failed; +} + +void test_rsdebug(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rsdebug_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rsdebug_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rslist.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rslist.rs new file mode 100644 index 0000000..5b2501f --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rslist.rs @@ -0,0 +1,107 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test_v11) + +#include "rs_graphics.rsh" + +float gDY; + +rs_font gFont; + +typedef struct ListAllocs_s { + rs_allocation text; + int result; +} ListAllocs; + +ListAllocs *gList; + +void init() { + gDY = 0.0f; +} + +int textPos = 0; + +int root(int launchID) { + + rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rsgClearDepth(1.0f); + + textPos -= (int)gDY*2; + gDY *= 0.95; + + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFont); + + rs_allocation listAlloc; + rsSetObject(&listAlloc, rsGetAllocation(gList)); + int allocSize = rsAllocationGetDimX(listAlloc); + + int width = rsgGetWidth(); + int height = rsgGetHeight(); + + int itemHeight = 80; + int totalItemHeight = itemHeight * allocSize; + + /* Prevent scrolling above the top of the list */ + int firstItem = height - totalItemHeight; + if (firstItem < 0) { + firstItem = 0; + } + + /* Prevent scrolling past the last line of the list */ + int lastItem = -1 * (totalItemHeight - height); + if (lastItem > 0) { + lastItem = 0; + } + + if (textPos > firstItem) { + textPos = firstItem; + } + else if (textPos < lastItem) { + textPos = lastItem; + } + + int currentYPos = itemHeight + textPos; + + for(int i = 0; i < allocSize; i ++) { + if(currentYPos - itemHeight > height) { + break; + } + + if(currentYPos > 0) { + switch(gList[i].result) { + case 1: /* Passed */ + rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f); + break; + case -1: /* Failed */ + rsgFontColor(0.9f, 0.5f, 0.5f, 1.0f); + break; + case 0: /* Still Testing */ + rsgFontColor(0.9f, 0.9f, 0.5f, 1.0f); + break; + default: /* Unknown */ + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + break; + } + rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0); + rsgDrawText(gList[i].text, 30, currentYPos - 32); + } + currentYPos += itemHeight; + } + + return 10; +} diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstime.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstime.rs new file mode 100644 index 0000000..5e3e078 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstime.rs @@ -0,0 +1,52 @@ +#include "shared.rsh" + +static bool basic_test(uint32_t index) { + bool failed = false; + + rs_time_t curTime = rsTime(0); + rs_tm tm; + rsDebug("curTime", curTime); + + rsLocaltime(&tm, &curTime); + + rsDebug("tm.tm_sec", tm.tm_sec); + rsDebug("tm.tm_min", tm.tm_min); + rsDebug("tm.tm_hour", tm.tm_hour); + rsDebug("tm.tm_mday", tm.tm_mday); + rsDebug("tm.tm_mon", tm.tm_mon); + rsDebug("tm.tm_year", tm.tm_year); + rsDebug("tm.tm_wday", tm.tm_wday); + rsDebug("tm.tm_yday", tm.tm_yday); + rsDebug("tm.tm_isdst", tm.tm_isdst); + + // Test a specific time (only valid for PST localtime) + curTime = 1294438893; + rsLocaltime(&tm, &curTime); + + _RS_ASSERT(tm.tm_sec == 33); + _RS_ASSERT(tm.tm_min == 21); + _RS_ASSERT(tm.tm_hour == 14); + _RS_ASSERT(tm.tm_mday == 7); + _RS_ASSERT(tm.tm_mon == 0); + _RS_ASSERT(tm.tm_year == 111); + _RS_ASSERT(tm.tm_wday == 5); + _RS_ASSERT(tm.tm_yday == 6); + _RS_ASSERT(tm.tm_isdst == 0); + + return failed; +} + +void test_rstime(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rstime_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rstime_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstypes.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstypes.rs new file mode 100644 index 0000000..f3bf244 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstypes.rs @@ -0,0 +1,79 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_element elementTest; +rs_type typeTest; +rs_allocation allocationTest; +rs_sampler samplerTest; +rs_script scriptTest; +rs_mesh meshTest; +rs_program_fragment program_fragmentTest; +rs_program_vertex program_vertexTest; +rs_program_raster program_rasterTest; +rs_program_store program_storeTest; +rs_font fontTest; + +rs_matrix4x4 matrix4x4Test; +rs_matrix3x3 matrix3x3Test; +rs_matrix2x2 matrix2x2Test; + +struct my_struct { + int i; + rs_font fontTestStruct; +}; + +static bool basic_test(uint32_t index) { + bool failed = false; + + rs_matrix4x4 matrix4x4TestLocal; + rs_matrix3x3 matrix3x3TestLocal; + rs_matrix2x2 matrix2x2TestLocal; + + // This test focuses primarily on compilation-time, not run-time. + rs_element elementTestLocal; + rs_type typeTestLocal; + rs_allocation allocationTestLocal; + rs_sampler samplerTestLocal; + rs_script scriptTestLocal; + rs_mesh meshTestLocal; + rs_program_fragment program_fragmentTestLocal; + rs_program_vertex program_vertexTestLocal; + rs_program_raster program_rasterTestLocal; + rs_program_store program_storeTestLocal; + rs_font fontTestLocal; + + rs_font fontTestLocalArray[4]; + + rs_font fontTestLocalPreInit = fontTest; + + struct my_struct structTest; + + rsSetObject(&fontTestLocal, fontTest); + //allocationTestLocal = allocationTest; + + rsSetObject(&fontTest, fontTestLocal); + //allocationTest = allocationTestLocal; + + /*for (int i = 0; i < 4; i++) { + rsSetObject(&fontTestLocalArray[i], fontTestLocal); + }*/ + + /*rsSetObject(&fontTest, fontTestLocalArray[3]);*/ + + return failed; +} + +void test_rstypes(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rstypes_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rstypes_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/shared.rsh new file mode 100644 index 0000000..6d34481 --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/shared.rsh @@ -0,0 +1,38 @@ +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test_v11) + +typedef struct TestResult_s { + rs_allocation name; + bool pass; + float score; + int64_t time; +} TestResult; +//TestResult *g_results; + +static int64_t g_time; + +static void start(void) { + g_time = rsUptimeMillis(); +} + +static float end(uint32_t idx) { + int64_t t = rsUptimeMillis() - g_time; + //g_results[idx].time = t; + //rsDebug("test time", (int)t); + return ((float)t) / 1000.f; +} + +#define _RS_ASSERT(b) \ +do { \ + if (!(b)) { \ + failed = true; \ + rsDebug(#b " FAILED", 0); \ + } \ +\ +} while (0) + +/* These constants must match those in UnitTest.java */ +static const int RS_MSG_TEST_PASSED = 100; +static const int RS_MSG_TEST_FAILED = 101; + diff --git a/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/test_root.rs b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/test_root.rs new file mode 100644 index 0000000..6dc83ba --- /dev/null +++ b/tests/RenderScriptTests/tests_v11/src/com/android/rs/test/test_root.rs @@ -0,0 +1,23 @@ +// Fountain test script +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + + +typedef struct TestResult { + rs_allocation name; + bool pass; + float score; +} TestResult_t; +TestResult_t *results; + +int root() { + + return 0; +} + + diff --git a/tests/RenderScriptTests/tests_v14/Android.mk b/tests/RenderScriptTests/tests_v14/Android.mk new file mode 100644 index 0000000..c4c3a37 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/Android.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := RSTest_v14 +LOCAL_SDK_VERSION := 14 + +include $(BUILD_PACKAGE) diff --git a/tests/RenderScriptTests/tests_v14/AndroidManifest.xml b/tests/RenderScriptTests/tests_v14/AndroidManifest.xml new file mode 100644 index 0000000..1cd9bbd --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/AndroidManifest.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rs.test_v14"> + <uses-sdk android:minSdkVersion="14" /> + <application + android:label="_RS_Test_v14" + android:icon="@drawable/test_pattern"> + <activity android:name="RSTest_v14" + android:screenOrientation="portrait"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/RenderScriptTests/tests_v14/res/drawable-nodpi/test_pattern.png b/tests/RenderScriptTests/tests_v14/res/drawable-nodpi/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/res/drawable-nodpi/test_pattern.png diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestCore.java new file mode 100644 index 0000000..f1e81a4 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestCore.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2008-2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.Timer; +import java.util.TimerTask; + + +public class RSTestCore { + int mWidth; + int mHeight; + Context mCtx; + + public RSTestCore(Context ctx) { + mCtx = ctx; + } + + private Resources mRes; + private RenderScriptGL mRS; + + private Font mFont; + ScriptField_ListAllocs_s mListAllocs; + int mLastX; + int mLastY; + private ScriptC_rslist mScript; + + private ArrayList<UnitTest> unitTests; + private ListIterator<UnitTest> test_iter; + private UnitTest activeTest; + private boolean stopTesting; + + /* Periodic timer for ensuring future tests get scheduled */ + private Timer mTimer; + public static final int RS_TIMER_PERIOD = 100; + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + stopTesting = false; + + mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist); + + unitTests = new ArrayList<UnitTest>(); + + unitTests.add(new UT_primitives(this, mRes, mCtx)); + unitTests.add(new UT_vector(this, mRes, mCtx)); + unitTests.add(new UT_rsdebug(this, mRes, mCtx)); + unitTests.add(new UT_rstime(this, mRes, mCtx)); + unitTests.add(new UT_rstypes(this, mRes, mCtx)); + unitTests.add(new UT_alloc(this, mRes, mCtx)); + unitTests.add(new UT_refcount(this, mRes, mCtx)); + unitTests.add(new UT_foreach(this, mRes, mCtx)); + unitTests.add(new UT_math(this, mRes, mCtx)); + unitTests.add(new UT_fp_mad(this, mRes, mCtx)); + /* + unitTests.add(new UnitTest(null, "<Pass>", 1)); + unitTests.add(new UnitTest()); + unitTests.add(new UnitTest(null, "<Fail>", -1)); + + for (int i = 0; i < 20; i++) { + unitTests.add(new UnitTest(null, "<Pass>", 1)); + } + */ + + UnitTest [] uta = new UnitTest[unitTests.size()]; + uta = unitTests.toArray(uta); + + mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length); + for (int i = 0; i < uta.length; i++) { + ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item(); + listElem.text = Allocation.createFromString(mRS, uta[i].name, Allocation.USAGE_SCRIPT); + listElem.result = uta[i].result; + mListAllocs.set(listElem, i, false); + uta[i].setItem(listElem); + } + + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + + mFont = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8); + mScript.set_gFont(mFont); + + mRS.bindRootScript(mScript); + + test_iter = unitTests.listIterator(); + refreshTestResults(); /* Kick off the first test */ + + TimerTask pTask = new TimerTask() { + public void run() { + refreshTestResults(); + } + }; + + mTimer = new Timer(); + mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD); + } + + public void checkAndRunNextTest() { + if (activeTest != null) { + if (!activeTest.isAlive()) { + /* Properly clean up on our last test */ + try { + activeTest.join(); + } + catch (InterruptedException e) { + } + activeTest = null; + } + } + + if (!stopTesting && activeTest == null) { + if (test_iter.hasNext()) { + activeTest = test_iter.next(); + activeTest.start(); + /* This routine will only get called once when a new test + * should start running. The message handler in UnitTest.java + * ensures this. */ + } + else { + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + } + } + } + + public void refreshTestResults() { + checkAndRunNextTest(); + + if (mListAllocs != null && mScript != null && mRS != null) { + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + mRS.bindRootScript(mScript); + } + } + + public void cleanup() { + stopTesting = true; + UnitTest t = activeTest; + + /* Stop periodic refresh of testing */ + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + + /* Wait to exit until we finish the current test */ + if (t != null) { + try { + t.join(); + } + catch (InterruptedException e) { + } + t = null; + } + + } + + public void newTouchPosition(float x, float y, float pressure, int id) { + } + + public void onActionDown(int x, int y) { + mScript.set_gDY(0.0f); + mLastX = x; + mLastY = y; + refreshTestResults(); + } + + public void onActionMove(int x, int y) { + int dx = mLastX - x; + int dy = mLastY - y; + + if (Math.abs(dy) <= 2) { + dy = 0; + } + + mScript.set_gDY(dy); + + mLastX = x; + mLastY = y; + refreshTestResults(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestView.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestView.java new file mode 100644 index 0000000..40192e4 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestView.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RSTestView extends RSSurfaceView { + + private Context mCtx; + + public RSTestView(Context context) { + super(context); + mCtx = context; + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RSTestCore mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScriptGL(sc); + mRS.setSurface(holder, w, h); + mRender = new RSTestCore(mCtx); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRender.cleanup(); + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + else if (act == ev.ACTION_MOVE) { + mRender.onActionMove((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTest_v14.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTest_v14.java new file mode 100644 index 0000000..da09691 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTest_v14.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class RSTest_v14 extends Activity { + //EventListener mListener = new EventListener(); + + private static final String LOG_TAG = "RSTest_v14"; + private static final boolean DEBUG = false; + private static final boolean LOG_ENABLED = false; + + private RSTestView mView; + + // get the current looper (from your Activity UI thread for instance + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new RSTestView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onPause(); + mView.pause(); + } + + @Override + protected void onStop() { + // Actually kill the app if we are stopping. We don't want to + // continue/resume this test ever. It should always start fresh. + finish(); + super.onStop(); + } + + static void log(String message) { + if (LOG_ENABLED) { + Log.v(LOG_TAG, message); + } + } + + +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_alloc.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_alloc.java new file mode 100644 index 0000000..da42b29 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_alloc.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_alloc extends UnitTest { + private Resources mRes; + + protected UT_alloc(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Alloc", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_alloc s) { + Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS)); + int X = 5; + int Y = 7; + int Z = 0; + s.set_dimX(X); + s.set_dimY(Y); + s.set_dimZ(Z); + typeBuilder.setX(X).setY(Y); + Allocation A = Allocation.createTyped(RS, typeBuilder.create()); + s.bind_a(A); + + typeBuilder = new Type.Builder(RS, Element.I32(RS)); + typeBuilder.setX(X).setY(Y).setFaces(true); + Allocation AFaces = Allocation.createTyped(RS, typeBuilder.create()); + s.set_aFaces(AFaces); + typeBuilder.setFaces(false).setMipmaps(true); + Allocation ALOD = Allocation.createTyped(RS, typeBuilder.create()); + s.set_aLOD(ALOD); + typeBuilder.setFaces(true).setMipmaps(true); + Allocation AFacesLOD = Allocation.createTyped(RS, typeBuilder.create()); + s.set_aFacesLOD(AFacesLOD); + + return; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_alloc s = new ScriptC_alloc(pRS, mRes, R.raw.alloc); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_alloc_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_foreach.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_foreach.java new file mode 100644 index 0000000..aeb5bb7 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_foreach.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_foreach extends UnitTest { + private Resources mRes; + private Allocation A; + + protected UT_foreach(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "ForEach", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_foreach s) { + Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS)); + int X = 5; + int Y = 7; + s.set_dimX(X); + s.set_dimY(Y); + typeBuilder.setX(X).setY(Y); + A = Allocation.createTyped(RS, typeBuilder.create()); + s.bind_a(A); + + return; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_foreach s = new ScriptC_foreach(pRS, mRes, R.raw.foreach); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.forEach_root(A); + s.invoke_foreach_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_fp_mad.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_fp_mad.java new file mode 100644 index 0000000..239496a --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_fp_mad.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_fp_mad extends UnitTest { + private Resources mRes; + + protected UT_fp_mad(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Fp_Mad", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad); + pRS.setMessageHandler(mRsMessage); + s.invoke_fp_mad_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_math.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_math.java new file mode 100644 index 0000000..7b135c4 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_math.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_math extends UnitTest { + private Resources mRes; + + protected UT_math(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Math", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_math s = new ScriptC_math(pRS, mRes, R.raw.math); + pRS.setMessageHandler(mRsMessage); + s.invoke_math_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_primitives.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_primitives.java new file mode 100644 index 0000000..d3c56f3 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_primitives.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_primitives extends UnitTest { + private Resources mRes; + + protected UT_primitives(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Primitives", ctx); + mRes = res; + } + + private boolean initializeGlobals(ScriptC_primitives s) { + float pF = s.get_floatTest(); + if (pF != 1.99f) { + return false; + } + s.set_floatTest(2.99f); + + double pD = s.get_doubleTest(); + if (pD != 2.05) { + return false; + } + s.set_doubleTest(3.05); + + byte pC = s.get_charTest(); + if (pC != -8) { + return false; + } + s.set_charTest((byte)-16); + + short pS = s.get_shortTest(); + if (pS != -16) { + return false; + } + s.set_shortTest((short)-32); + + int pI = s.get_intTest(); + if (pI != -32) { + return false; + } + s.set_intTest(-64); + + long pL = s.get_longTest(); + if (pL != 17179869184l) { + return false; + } + s.set_longTest(17179869185l); + + long puL = s.get_ulongTest(); + if (puL != 4611686018427387904L) { + return false; + } + s.set_ulongTest(4611686018427387903L); + + + long pLL = s.get_longlongTest(); + if (pLL != 68719476736L) { + return false; + } + s.set_longlongTest(68719476735L); + + long pu64 = s.get_uint64_tTest(); + if (pu64 != 117179869184l) { + return false; + } + s.set_uint64_tTest(117179869185l); + + return true; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives); + pRS.setMessageHandler(mRsMessage); + if (!initializeGlobals(s)) { + // initializeGlobals failed + result = -1; + } else { + s.invoke_primitives_test(0, 0); + pRS.finish(); + waitForMessage(); + } + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_refcount.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_refcount.java new file mode 100644 index 0000000..05a516b --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_refcount.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_refcount extends UnitTest { + private Resources mRes; + + protected UT_refcount(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Refcount", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_refcount s) { + Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS)); + int X = 500; + int Y = 700; + typeBuilder.setX(X).setY(Y); + Allocation A = Allocation.createTyped(RS, typeBuilder.create()); + s.set_globalA(A); + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + pRS.setMessageHandler(mRsMessage); + ScriptC_refcount s = new ScriptC_refcount(pRS, mRes, R.raw.refcount); + initializeGlobals(pRS, s); + s.invoke_refcount_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rsdebug.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rsdebug.java new file mode 100644 index 0000000..95e92ee --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rsdebug.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rsdebug extends UnitTest { + private Resources mRes; + + protected UT_rsdebug(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsDebug", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rsdebug(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstime.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstime.java new file mode 100644 index 0000000..a72ede9 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstime.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rstime extends UnitTest { + private Resources mRes; + + protected UT_rstime(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsTime", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rstime s = new ScriptC_rstime(pRS, mRes, R.raw.rstime); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rstime(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstypes.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstypes.java new file mode 100644 index 0000000..ab96867 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstypes.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_rstypes extends UnitTest { + private Resources mRes; + + protected UT_rstypes(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "rsTypes", ctx); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_rstypes s = new ScriptC_rstypes(pRS, mRes, R.raw.rstypes); + pRS.setMessageHandler(mRsMessage); + s.invoke_test_rstypes(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_vector.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_vector.java new file mode 100644 index 0000000..657413e --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_vector.java @@ -0,0 +1,318 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test_v14; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_vector extends UnitTest { + private Resources mRes; + + protected UT_vector(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "Vector", ctx); + mRes = res; + } + + private boolean initializeGlobals(ScriptC_vector s) { + Float2 F2 = s.get_f2(); + if (F2.x != 1.0f || F2.y != 2.0f) { + return false; + } + F2.x = 2.99f; + F2.y = 3.99f; + s.set_f2(F2); + + Float3 F3 = s.get_f3(); + if (F3.x != 1.0f || F3.y != 2.0f || F3.z != 3.0f) { + return false; + } + F3.x = 2.99f; + F3.y = 3.99f; + F3.z = 4.99f; + s.set_f3(F3); + + Float4 F4 = s.get_f4(); + if (F4.x != 1.0f || F4.y != 2.0f || F4.z != 3.0f || F4.w != 4.0f) { + return false; + } + F4.x = 2.99f; + F4.y = 3.99f; + F4.z = 4.99f; + F4.w = 5.99f; + s.set_f4(F4); + + Double2 D2 = s.get_d2(); + if (D2.x != 1.0 || D2.y != 2.0) { + return false; + } + D2.x = 2.99; + D2.y = 3.99; + s.set_d2(D2); + + Double3 D3 = s.get_d3(); + if (D3.x != 1.0 || D3.y != 2.0 || D3.z != 3.0) { + return false; + } + D3.x = 2.99; + D3.y = 3.99; + D3.z = 4.99; + s.set_d3(D3); + + Double4 D4 = s.get_d4(); + if (D4.x != 1.0 || D4.y != 2.0 || D4.z != 3.0 || D4.w != 4.0) { + return false; + } + D4.x = 2.99; + D4.y = 3.99; + D4.z = 4.99; + D4.w = 5.99; + s.set_d4(D4); + + Byte2 B2 = s.get_i8_2(); + if (B2.x != 1 || B2.y != 2) { + return false; + } + B2.x = 2; + B2.y = 3; + s.set_i8_2(B2); + + Byte3 B3 = s.get_i8_3(); + if (B3.x != 1 || B3.y != 2 || B3.z != 3) { + return false; + } + B3.x = 2; + B3.y = 3; + B3.z = 4; + s.set_i8_3(B3); + + Byte4 B4 = s.get_i8_4(); + if (B4.x != 1 || B4.y != 2 || B4.z != 3 || B4.w != 4) { + return false; + } + B4.x = 2; + B4.y = 3; + B4.z = 4; + B4.w = 5; + s.set_i8_4(B4); + + Short2 S2 = s.get_u8_2(); + if (S2.x != 1 || S2.y != 2) { + return false; + } + S2.x = 2; + S2.y = 3; + s.set_u8_2(S2); + + Short3 S3 = s.get_u8_3(); + if (S3.x != 1 || S3.y != 2 || S3.z != 3) { + return false; + } + S3.x = 2; + S3.y = 3; + S3.z = 4; + s.set_u8_3(S3); + + Short4 S4 = s.get_u8_4(); + if (S4.x != 1 || S4.y != 2 || S4.z != 3 || S4.w != 4) { + return false; + } + S4.x = 2; + S4.y = 3; + S4.z = 4; + S4.w = 5; + s.set_u8_4(S4); + + S2 = s.get_i16_2(); + if (S2.x != 1 || S2.y != 2) { + return false; + } + S2.x = 2; + S2.y = 3; + s.set_i16_2(S2); + + S3 = s.get_i16_3(); + if (S3.x != 1 || S3.y != 2 || S3.z != 3) { + return false; + } + S3.x = 2; + S3.y = 3; + S3.z = 4; + s.set_i16_3(S3); + + S4 = s.get_i16_4(); + if (S4.x != 1 || S4.y != 2 || S4.z != 3 || S4.w != 4) { + return false; + } + S4.x = 2; + S4.y = 3; + S4.z = 4; + S4.w = 5; + s.set_i16_4(S4); + + Int2 I2 = s.get_u16_2(); + if (I2.x != 1 || I2.y != 2) { + return false; + } + I2.x = 2; + I2.y = 3; + s.set_u16_2(I2); + + Int3 I3 = s.get_u16_3(); + if (I3.x != 1 || I3.y != 2 || I3.z != 3) { + return false; + } + I3.x = 2; + I3.y = 3; + I3.z = 4; + s.set_u16_3(I3); + + Int4 I4 = s.get_u16_4(); + if (I4.x != 1 || I4.y != 2 || I4.z != 3 || I4.w != 4) { + return false; + } + I4.x = 2; + I4.y = 3; + I4.z = 4; + I4.w = 5; + s.set_u16_4(I4); + + I2 = s.get_i32_2(); + if (I2.x != 1 || I2.y != 2) { + return false; + } + I2.x = 2; + I2.y = 3; + s.set_i32_2(I2); + + I3 = s.get_i32_3(); + if (I3.x != 1 || I3.y != 2 || I3.z != 3) { + return false; + } + I3.x = 2; + I3.y = 3; + I3.z = 4; + s.set_i32_3(I3); + + I4 = s.get_i32_4(); + if (I4.x != 1 || I4.y != 2 || I4.z != 3 || I4.w != 4) { + return false; + } + I4.x = 2; + I4.y = 3; + I4.z = 4; + I4.w = 5; + s.set_i32_4(I4); + + Long2 L2 = s.get_u32_2(); + if (L2.x != 1 || L2.y != 2) { + return false; + } + L2.x = 2; + L2.y = 3; + s.set_u32_2(L2); + + Long3 L3 = s.get_u32_3(); + if (L3.x != 1 || L3.y != 2 || L3.z != 3) { + return false; + } + L3.x = 2; + L3.y = 3; + L3.z = 4; + s.set_u32_3(L3); + + Long4 L4 = s.get_u32_4(); + if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) { + return false; + } + L4.x = 2; + L4.y = 3; + L4.z = 4; + L4.w = 5; + s.set_u32_4(L4); + + L2 = s.get_i64_2(); + if (L2.x != 1 || L2.y != 2) { + return false; + } + L2.x = 2; + L2.y = 3; + s.set_i64_2(L2); + + L3 = s.get_i64_3(); + if (L3.x != 1 || L3.y != 2 || L3.z != 3) { + return false; + } + L3.x = 2; + L3.y = 3; + L3.z = 4; + s.set_i64_3(L3); + + L4 = s.get_i64_4(); + if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) { + return false; + } + L4.x = 2; + L4.y = 3; + L4.z = 4; + L4.w = 5; + s.set_i64_4(L4); + + L2 = s.get_u64_2(); + if (L2.x != 1 || L2.y != 2) { + return false; + } + L2.x = 2; + L2.y = 3; + s.set_u64_2(L2); + + L3 = s.get_u64_3(); + if (L3.x != 1 || L3.y != 2 || L3.z != 3) { + return false; + } + L3.x = 2; + L3.y = 3; + L3.z = 4; + s.set_u64_3(L3); + + L4 = s.get_u64_4(); + if (L4.x != 1 || L4.y != 2 || L4.z != 3 || L4.w != 4) { + return false; + } + L4.x = 2; + L4.y = 3; + L4.z = 4; + L4.w = 5; + s.set_u64_4(L4); + + return true; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_vector s = new ScriptC_vector(pRS, mRes, R.raw.vector); + pRS.setMessageHandler(mRsMessage); + if (!initializeGlobals(s)) { + result = -1; + } else { + s.invoke_vector_test(); + pRS.finish(); + waitForMessage(); + } + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UnitTest.java new file mode 100644 index 0000000..558a252 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UnitTest.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010 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.test_v14; +import android.content.Context; +import android.util.Log; +import android.renderscript.RenderScript.RSMessageHandler; + +public class UnitTest extends Thread { + public String name; + public int result; + private ScriptField_ListAllocs_s.Item mItem; + private RSTestCore mRSTC; + private boolean msgHandled; + protected Context mCtx; + + /* These constants must match those in shared.rsh */ + public static final int RS_MSG_TEST_PASSED = 100; + public static final int RS_MSG_TEST_FAILED = 101; + + private static int numTests = 0; + public int testID; + + protected UnitTest(RSTestCore rstc, String n, int initResult, Context ctx) { + super(); + mRSTC = rstc; + name = n; + msgHandled = false; + mCtx = ctx; + result = initResult; + testID = numTests++; + } + + protected UnitTest(RSTestCore rstc, String n, Context ctx) { + this(rstc, n, 0, ctx); + } + + protected UnitTest(RSTestCore rstc, Context ctx) { + this (rstc, "<Unknown>", ctx); + } + + protected UnitTest(Context ctx) { + this (null, ctx); + } + + protected void _RS_ASSERT(String message, boolean b) { + if(b == false) { + result = -1; + Log.e(name, message + " FAILED"); + } + } + + protected void updateUI() { + if (mItem != null) { + mItem.result = result; + msgHandled = true; + try { + mRSTC.refreshTestResults(); + } + catch (IllegalStateException e) { + /* Ignore the case where our message receiver has been + disconnected. This happens when we leave the application + before it finishes running all of the unit tests. */ + } + } + } + + protected RSMessageHandler mRsMessage = new RSMessageHandler() { + public void run() { + if (result == 0) { + switch (mID) { + case RS_MSG_TEST_PASSED: + result = 1; + break; + case RS_MSG_TEST_FAILED: + result = -1; + break; + default: + RSTest_v14.log("Unit test got unexpected message"); + return; + } + } + + updateUI(); + } + }; + + public void waitForMessage() { + while (!msgHandled) { + yield(); + } + } + + public void setItem(ScriptField_ListAllocs_s.Item item) { + mItem = item; + } + + public void run() { + /* This method needs to be implemented for each subclass */ + if (mRSTC != null) { + mRSTC.refreshTestResults(); + } + } +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/alloc.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/alloc.rs new file mode 100644 index 0000000..3116e5a --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/alloc.rs @@ -0,0 +1,94 @@ +#include "shared.rsh" + +int *a; +int dimX; +int dimY; +int dimZ; + +rs_allocation aFaces; +rs_allocation aLOD; +rs_allocation aFacesLOD; + +static bool test_alloc_dims() { + bool failed = false; + int i, j; + + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + a[i + j * dimX] = i + j * dimX; + } + } + + rs_allocation alloc = rsGetAllocation(a); + _RS_ASSERT(rsAllocationGetDimX(alloc) == dimX); + _RS_ASSERT(rsAllocationGetDimY(alloc) == dimY); + _RS_ASSERT(rsAllocationGetDimZ(alloc) == dimZ); + + // Test 2D addressing + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + rsDebug("Verifying ", i + j * dimX); + const void *p = rsGetElementAt(alloc, i, j); + int val = *(const int *)p; + _RS_ASSERT(val == (i + j * dimX)); + } + } + + // Test 1D addressing + for (i = 0; i < dimX * dimY; i++) { + rsDebug("Verifying ", i); + const void *p = rsGetElementAt(alloc, i); + int val = *(const int *)p; + _RS_ASSERT(val == i); + } + + // Test 3D addressing + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + rsDebug("Verifying ", i + j * dimX); + const void *p = rsGetElementAt(alloc, i, j, 0); + int val = *(const int *)p; + _RS_ASSERT(val == (i + j * dimX)); + } + } + + _RS_ASSERT(rsAllocationGetDimX(aFaces) == dimX); + _RS_ASSERT(rsAllocationGetDimY(aFaces) == dimY); + _RS_ASSERT(rsAllocationGetDimZ(aFaces) == dimZ); + _RS_ASSERT(rsAllocationGetDimFaces(aFaces) != 0); + _RS_ASSERT(rsAllocationGetDimLOD(aFaces) == 0); + + _RS_ASSERT(rsAllocationGetDimX(aLOD) == dimX); + _RS_ASSERT(rsAllocationGetDimY(aLOD) == dimY); + _RS_ASSERT(rsAllocationGetDimZ(aLOD) == dimZ); + _RS_ASSERT(rsAllocationGetDimFaces(aLOD) == 0); + _RS_ASSERT(rsAllocationGetDimLOD(aLOD) != 0); + + _RS_ASSERT(rsAllocationGetDimX(aFacesLOD) == dimX); + _RS_ASSERT(rsAllocationGetDimY(aFacesLOD) == dimY); + _RS_ASSERT(rsAllocationGetDimZ(aFacesLOD) == dimZ); + _RS_ASSERT(rsAllocationGetDimFaces(aFacesLOD) != 0); + _RS_ASSERT(rsAllocationGetDimLOD(aFacesLOD) != 0); + + if (failed) { + rsDebug("test_alloc_dims FAILED", 0); + } + else { + rsDebug("test_alloc_dims PASSED", 0); + } + + return failed; +} + +void alloc_test() { + bool failed = false; + failed |= test_alloc_dims(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/foreach.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/foreach.rs new file mode 100644 index 0000000..3ba3eef --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/foreach.rs @@ -0,0 +1,42 @@ +#include "shared.rsh" + +int *a; +int dimX; +int dimY; + +void root(int *out, uint32_t x, uint32_t y) { + *out = x + y * dimX; +} + +static bool test_foreach_output() { + bool failed = false; + int i, j; + + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + _RS_ASSERT(a[i + j * dimX] == (i + j * dimX)); + } + } + + if (failed) { + rsDebug("test_foreach_output FAILED", 0); + } + else { + rsDebug("test_foreach_output PASSED", 0); + } + + return failed; +} + +void foreach_test() { + bool failed = false; + failed |= test_foreach_output(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/fp_mad.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/fp_mad.rs new file mode 100644 index 0000000..b6f2b2a --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/fp_mad.rs @@ -0,0 +1,174 @@ +#include "shared.rsh" + +const int TEST_COUNT = 1; + +static float data_f1[1025]; +static float4 data_f4[1025]; + +static void test_mad4(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 80); ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = (data_f4[i] * 0.02f + + data_f4[i+1] * 0.04f + + data_f4[i+2] * 0.05f + + data_f4[i+3] * 0.1f + + data_f4[i+4] * 0.2f + + data_f4[i+5] * 0.2f + + data_f4[i+6] * 0.1f + + data_f4[i+7] * 0.05f + + data_f4[i+8] * 0.04f + + data_f4[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad4 M ops", 1000.f / time); +} + +static void test_mad(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 20); ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = (data_f1[i] * 0.02f + + data_f1[i+1] * 0.04f + + data_f1[i+2] * 0.05f + + data_f1[i+3] * 0.1f + + data_f1[i+4] * 0.2f + + data_f1[i+5] * 0.2f + + data_f1[i+6] * 0.1f + + data_f1[i+7] * 0.05f + + data_f1[i+8] * 0.04f + + data_f1[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad M ops", 1000.f / time); +} + +static void test_norm(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = normalize(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_norm M ops", 10.f / time); +} + +static void test_sincos4(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10 / 4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = sin(data_f4[i]) * cos(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos4 M ops", 10.f / time); +} + +static void test_sincos(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = sin(data_f1[i]) * cos(data_f1[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos M ops", 10.f / time); +} + +static void test_clamp(uint32_t index) { + start(); + + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = clamp(data_f1[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp M ops", 100.f / time); + + start(); + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + if (data_f1[i] < -1.f) data_f1[i] = -1.f; + if (data_f1[i] > -1.f) data_f1[i] = 1.f; + } + } + + time = end(index); + rsDebug("fp_clamp ref M ops", 100.f / time); +} + +static void test_clamp4(uint32_t index) { + start(); + + float total = 0; + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100 /4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = clamp(data_f4[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp4 M ops", 100.f / time); +} + +void fp_mad_test(uint32_t index, int test_num) { + int x; + for (x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f; + data_f4[x].x = (x & 0xf) * 0.1f; + data_f4[x].y = (x & 0xf0) * 0.1f; + data_f4[x].z = (x & 0x33) * 0.1f; + data_f4[x].w = (x & 0x77) * 0.1f; + } + + test_mad4(index); + test_mad(index); + + for (x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f + 1.f; + data_f4[x].x = (x & 0xf) * 0.1f + 1.f; + data_f4[x].y = (x & 0xf0) * 0.1f + 1.f; + data_f4[x].z = (x & 0x33) * 0.1f + 1.f; + data_f4[x].w = (x & 0x77) * 0.1f + 1.f; + } + + test_norm(index); + test_sincos4(index); + test_sincos(index); + test_clamp4(index); + test_clamp(index); + + // TODO Actually verify test result accuracy + rsDebug("fp_mad_test PASSED", 0); + rsSendToClientBlocking(RS_MSG_TEST_PASSED); +} + + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs new file mode 100644 index 0000000..e6b37f6 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs @@ -0,0 +1,462 @@ +#include "shared.rsh" + +// Testing math library + +volatile float f1; +volatile float2 f2; +volatile float3 f3; +volatile float4 f4; + +volatile int i1; +volatile int2 i2; +volatile int3 i3; +volatile int4 i4; + +volatile uint ui1; +volatile uint2 ui2; +volatile uint3 ui3; +volatile uint4 ui4; + +volatile short s1; +volatile short2 s2; +volatile short3 s3; +volatile short4 s4; + +volatile ushort us1; +volatile ushort2 us2; +volatile ushort3 us3; +volatile ushort4 us4; + +volatile char c1; +volatile char2 c2; +volatile char3 c3; +volatile char4 c4; + +volatile uchar uc1; +volatile uchar2 uc2; +volatile uchar3 uc3; +volatile uchar4 uc4; + +#define DECL_INT(prefix) \ +volatile char prefix##_c_1 = 1; \ +volatile char2 prefix##_c_2 = 1; \ +volatile char3 prefix##_c_3 = 1; \ +volatile char4 prefix##_c_4 = 1; \ +volatile uchar prefix##_uc_1 = 1; \ +volatile uchar2 prefix##_uc_2 = 1; \ +volatile uchar3 prefix##_uc_3 = 1; \ +volatile uchar4 prefix##_uc_4 = 1; \ +volatile short prefix##_s_1 = 1; \ +volatile short2 prefix##_s_2 = 1; \ +volatile short3 prefix##_s_3 = 1; \ +volatile short4 prefix##_s_4 = 1; \ +volatile ushort prefix##_us_1 = 1; \ +volatile ushort2 prefix##_us_2 = 1; \ +volatile ushort3 prefix##_us_3 = 1; \ +volatile ushort4 prefix##_us_4 = 1; \ +volatile int prefix##_i_1 = 1; \ +volatile int2 prefix##_i_2 = 1; \ +volatile int3 prefix##_i_3 = 1; \ +volatile int4 prefix##_i_4 = 1; \ +volatile uint prefix##_ui_1 = 1; \ +volatile uint2 prefix##_ui_2 = 1; \ +volatile uint3 prefix##_ui_3 = 1; \ +volatile uint4 prefix##_ui_4 = 1; \ +volatile long prefix##_l_1 = 1; \ +volatile ulong prefix##_ul_1 = 1; + +DECL_INT(res) +DECL_INT(src1) +DECL_INT(src2) + +#define TEST_INT_OP_TYPE(op, type) \ +rsDebug("Testing " #op " for " #type "1", i++); \ +res_##type##_1 = src1_##type##_1 op src2_##type##_1; \ +rsDebug("Testing " #op " for " #type "2", i++); \ +res_##type##_2 = src1_##type##_2 op src2_##type##_2; \ +rsDebug("Testing " #op " for " #type "3", i++); \ +res_##type##_3 = src1_##type##_3 op src2_##type##_3; \ +rsDebug("Testing " #op " for " #type "4", i++); \ +res_##type##_4 = src1_##type##_4 op src2_##type##_4; + +#define TEST_INT_OP(op) \ +TEST_INT_OP_TYPE(op, c) \ +TEST_INT_OP_TYPE(op, uc) \ +TEST_INT_OP_TYPE(op, s) \ +TEST_INT_OP_TYPE(op, us) \ +TEST_INT_OP_TYPE(op, i) \ +TEST_INT_OP_TYPE(op, ui) \ +rsDebug("Testing " #op " for l1", i++); \ +res_l_1 = src1_l_1 op src2_l_1; \ +rsDebug("Testing " #op " for ul1", i++); \ +res_ul_1 = src1_ul_1 op src2_ul_1; + +#define TEST_XN_FUNC_YN(typeout, fnc, typein) \ + res_##typeout##_1 = fnc(src1_##typein##_1); \ + res_##typeout##_2 = fnc(src1_##typein##_2); \ + res_##typeout##_3 = fnc(src1_##typein##_3); \ + res_##typeout##_4 = fnc(src1_##typein##_4); + +#define TEST_XN_FUNC_XN_XN(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \ + res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \ + res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \ + res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4); + +#define TEST_X_FUNC_X_X_X(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1); + +#define TEST_IN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, uc) \ + TEST_XN_FUNC_YN(c, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, us) \ + TEST_XN_FUNC_YN(s, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, ui) \ + TEST_XN_FUNC_YN(i, fnc, i) + +#define TEST_UIN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, i) \ + +#define TEST_IN_FUNC_IN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_XN_XN(uc, fnc) \ + TEST_XN_FUNC_XN_XN(c, fnc) \ + TEST_XN_FUNC_XN_XN(us, fnc) \ + TEST_XN_FUNC_XN_XN(s, fnc) \ + TEST_XN_FUNC_XN_XN(ui, fnc) \ + TEST_XN_FUNC_XN_XN(i, fnc) + +#define TEST_I_FUNC_I_I_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_X_FUNC_X_X_X(uc, fnc) \ + TEST_X_FUNC_X_X_X(c, fnc) \ + TEST_X_FUNC_X_X_X(us, fnc) \ + TEST_X_FUNC_X_X_X(s, fnc) \ + TEST_X_FUNC_X_X_X(ui, fnc) \ + TEST_X_FUNC_X_X_X(i, fnc) + +#define TEST_FN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f2 = fnc(f2); \ + f3 = fnc(f3); \ + f4 = fnc(f4); + +#define TEST_FN_FUNC_FN_PFN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (float*) &f1); \ + f2 = fnc(f2, (float2*) &f2); \ + f3 = fnc(f3, (float3*) &f3); \ + f4 = fnc(f4, (float4*) &f4); + +#define TEST_FN_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f2); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_F34_FUNC_F34_F34(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f1); \ + f3 = fnc(f3, f1); \ + f4 = fnc(f4, f1); + +#define TEST_F_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f1 = fnc(f2); \ + f1 = fnc(f3); \ + f1 = fnc(f4); + +#define TEST_F_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f1 = fnc(f2, f2); \ + f1 = fnc(f3, f3); \ + f1 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i2); \ + f3 = fnc(f3, i3); \ + f4 = fnc(f4, i4); + +#define TEST_FN_FUNC_FN_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i1); \ + f3 = fnc(f3, i1); \ + f4 = fnc(f4, i1); + +#define TEST_FN_FUNC_FN_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f2, f2); \ + f3 = fnc(f3, f3, f3); \ + f4 = fnc(f4, f4, f4); + +#define TEST_FN_FUNC_FN_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f1, f1); \ + f3 = fnc(f3, f1, f1); \ + f4 = fnc(f4, f1, f1); + +#define TEST_FN_FUNC_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (int*) &i1); \ + f2 = fnc(f2, (int2*) &i2); \ + f3 = fnc(f3, (int3*) &i3); \ + f4 = fnc(f4, (int4*) &i4); + +#define TEST_FN_FUNC_FN_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, (int*) &i1); \ + f2 = fnc(f2, f2, (int2*) &i2); \ + f3 = fnc(f3, f3, (int3*) &i3); \ + f4 = fnc(f4, f4, (int4*) &i4); + +#define TEST_IN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + i1 = fnc(f1); \ + i2 = fnc(f2); \ + i3 = fnc(f3); \ + i4 = fnc(f4); + +static bool test_fp_math(uint32_t index) { + bool failed = false; + start(); + + TEST_FN_FUNC_FN(acos); + TEST_FN_FUNC_FN(acosh); + TEST_FN_FUNC_FN(acospi); + TEST_FN_FUNC_FN(asin); + TEST_FN_FUNC_FN(asinh); + TEST_FN_FUNC_FN(asinpi); + TEST_FN_FUNC_FN(atan); + TEST_FN_FUNC_FN_FN(atan2); + TEST_FN_FUNC_FN(atanh); + TEST_FN_FUNC_FN(atanpi); + TEST_FN_FUNC_FN_FN(atan2pi); + TEST_FN_FUNC_FN(cbrt); + TEST_FN_FUNC_FN(ceil); + TEST_FN_FUNC_FN_FN_FN(clamp); + TEST_FN_FUNC_FN_FN_F(clamp); + TEST_FN_FUNC_FN_FN(copysign); + TEST_FN_FUNC_FN(cos); + TEST_FN_FUNC_FN(cosh); + TEST_FN_FUNC_FN(cospi); + TEST_F34_FUNC_F34_F34(cross); + TEST_FN_FUNC_FN(degrees); + TEST_F_FUNC_FN_FN(distance); + TEST_F_FUNC_FN_FN(dot); + TEST_FN_FUNC_FN(erfc); + TEST_FN_FUNC_FN(erf); + TEST_FN_FUNC_FN(exp); + TEST_FN_FUNC_FN(exp2); + TEST_FN_FUNC_FN(exp10); + TEST_FN_FUNC_FN(expm1); + TEST_FN_FUNC_FN(fabs); + TEST_FN_FUNC_FN_FN(fdim); + TEST_FN_FUNC_FN(floor); + TEST_FN_FUNC_FN_FN_FN(fma); + TEST_FN_FUNC_FN_FN(fmax); + TEST_FN_FUNC_FN_F(fmax); + TEST_FN_FUNC_FN_FN(fmin); + TEST_FN_FUNC_FN_F(fmin); + TEST_FN_FUNC_FN_FN(fmod); + TEST_FN_FUNC_FN_PFN(fract); + TEST_FN_FUNC_FN_PIN(frexp); + TEST_FN_FUNC_FN_FN(hypot); + TEST_IN_FUNC_FN(ilogb); + TEST_FN_FUNC_FN_IN(ldexp); + TEST_FN_FUNC_FN_I(ldexp); + TEST_F_FUNC_FN(length); + TEST_FN_FUNC_FN(lgamma); + TEST_FN_FUNC_FN_PIN(lgamma); + TEST_FN_FUNC_FN(log); + TEST_FN_FUNC_FN(log2); + TEST_FN_FUNC_FN(log10); + TEST_FN_FUNC_FN(log1p); + TEST_FN_FUNC_FN(logb); + TEST_FN_FUNC_FN_FN_FN(mad); + TEST_FN_FUNC_FN_FN(max); + TEST_FN_FUNC_FN_F(max); + TEST_FN_FUNC_FN_FN(min); + TEST_FN_FUNC_FN_F(min); + TEST_FN_FUNC_FN_FN_FN(mix); + TEST_FN_FUNC_FN_FN_F(mix); + TEST_FN_FUNC_FN_PFN(modf); + // nan + TEST_FN_FUNC_FN_FN(nextafter); + TEST_FN_FUNC_FN(normalize); + TEST_FN_FUNC_FN_FN(pow); + TEST_FN_FUNC_FN_IN(pown); + TEST_FN_FUNC_FN_FN(powr); + TEST_FN_FUNC_FN(radians); + TEST_FN_FUNC_FN_FN(remainder); + TEST_FN_FUNC_FN_FN_PIN(remquo); + TEST_FN_FUNC_FN(rint); + TEST_FN_FUNC_FN_IN(rootn); + TEST_FN_FUNC_FN(round); + TEST_FN_FUNC_FN(rsqrt); + TEST_FN_FUNC_FN(sign); + TEST_FN_FUNC_FN(sin); + TEST_FN_FUNC_FN_PFN(sincos); + TEST_FN_FUNC_FN(sinh); + TEST_FN_FUNC_FN(sinpi); + TEST_FN_FUNC_FN(sqrt); + TEST_FN_FUNC_FN_FN(step); + TEST_FN_FUNC_FN_F(step); + TEST_FN_FUNC_FN(tan); + TEST_FN_FUNC_FN(tanh); + TEST_FN_FUNC_FN(tanpi); + TEST_FN_FUNC_FN(tgamma); + TEST_FN_FUNC_FN(trunc); + + float time = end(index); + + if (failed) { + rsDebug("test_fp_math FAILED", time); + } + else { + rsDebug("test_fp_math PASSED", time); + } + + return failed; +} + +static bool test_int_math(uint32_t index) { + bool failed = false; + start(); + + TEST_UIN_FUNC_IN(abs); + TEST_IN_FUNC_IN(clz); + TEST_IN_FUNC_IN_IN(min); + TEST_IN_FUNC_IN_IN(max); + TEST_I_FUNC_I_I_I(rsClamp); + + float time = end(index); + + if (failed) { + rsDebug("test_int_math FAILED", time); + } + else { + rsDebug("test_int_math PASSED", time); + } + + return failed; +} + +static bool test_basic_operators() { + bool failed = false; + int i = 0; + + TEST_INT_OP(+); + TEST_INT_OP(-); + TEST_INT_OP(*); + TEST_INT_OP(/); + TEST_INT_OP(%); + TEST_INT_OP(<<); + TEST_INT_OP(>>); + + if (failed) { + rsDebug("test_basic_operators FAILED", 0); + } + else { + rsDebug("test_basic_operators PASSED", 0); + } + + return failed; +} + +#define TEST_CVT(to, from, type) \ +rsDebug("Testing convert from " #from " to " #to, 0); \ +to##1 = from##1; \ +to##2 = convert_##type##2(from##2); \ +to##3 = convert_##type##3(from##3); \ +to##4 = convert_##type##4(from##4); + +#define TEST_CVT_MATRIX(to, type) \ +TEST_CVT(to, c, type); \ +TEST_CVT(to, uc, type); \ +TEST_CVT(to, s, type); \ +TEST_CVT(to, us, type); \ +TEST_CVT(to, i, type); \ +TEST_CVT(to, ui, type); \ +TEST_CVT(to, f, type); \ + +static bool test_convert() { + bool failed = false; + + TEST_CVT_MATRIX(c, char); + TEST_CVT_MATRIX(uc, uchar); + TEST_CVT_MATRIX(s, short); + TEST_CVT_MATRIX(us, ushort); + TEST_CVT_MATRIX(i, int); + TEST_CVT_MATRIX(ui, uint); + TEST_CVT_MATRIX(f, float); + + if (failed) { + rsDebug("test_convert FAILED", 0); + } + else { + rsDebug("test_convert PASSED", 0); + } + + return failed; +} + +#define INIT_PREFIX_TYPE(prefix, type) \ +prefix##_##type##_1 = 1; \ +prefix##_##type##_2.x = 1; \ +prefix##_##type##_2.y = 1; \ +prefix##_##type##_3.x = 1; \ +prefix##_##type##_3.y = 1; \ +prefix##_##type##_3.z = 1; \ +prefix##_##type##_4.x = 1; \ +prefix##_##type##_4.y = 1; \ +prefix##_##type##_4.z = 1; \ +prefix##_##type##_4.w = 1; + +#define INIT_TYPE(type) \ +INIT_PREFIX_TYPE(src1, type) \ +INIT_PREFIX_TYPE(src2, type) \ +INIT_PREFIX_TYPE(res, type) + +#define INIT_ALL \ +INIT_TYPE(c); \ +INIT_TYPE(uc); \ +INIT_TYPE(s); \ +INIT_TYPE(us); \ +INIT_TYPE(i); \ +INIT_TYPE(ui); + +void math_test(uint32_t index, int test_num) { + bool failed = false; + INIT_ALL; + failed |= test_convert(); + failed |= test_fp_math(index); + failed |= test_int_math(index); + failed |= test_basic_operators(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.bak b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.bak new file mode 100644 index 0000000..ad802ca --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.bak @@ -0,0 +1,423 @@ +#include "shared.rsh" + +// Testing math library + +volatile float f1; +volatile float2 f2; +volatile float3 f3; +volatile float4 f4; + +volatile int i1; +volatile int2 i2; +volatile int3 i3; +volatile int4 i4; + +volatile uint ui1; +volatile uint2 ui2; +volatile uint3 ui3; +volatile uint4 ui4; + +volatile short s1; +volatile short2 s2; +volatile short3 s3; +volatile short4 s4; + +volatile ushort us1; +volatile ushort2 us2; +volatile ushort3 us3; +volatile ushort4 us4; + +volatile char c1; +volatile char2 c2; +volatile char3 c3; +volatile char4 c4; + +volatile uchar uc1; +volatile uchar2 uc2; +volatile uchar3 uc3; +volatile uchar4 uc4; + +#define DECL_INT(prefix) \ +volatile char prefix##_c_1 = 1; \ +volatile char2 prefix##_c_2 = 1; \ +volatile char3 prefix##_c_3 = 1; \ +volatile char4 prefix##_c_4 = 1; \ +volatile uchar prefix##_uc_1 = 1; \ +volatile uchar2 prefix##_uc_2 = 1; \ +volatile uchar3 prefix##_uc_3 = 1; \ +volatile uchar4 prefix##_uc_4 = 1; \ +volatile short prefix##_s_1 = 1; \ +volatile short2 prefix##_s_2 = 1; \ +volatile short3 prefix##_s_3 = 1; \ +volatile short4 prefix##_s_4 = 1; \ +volatile ushort prefix##_us_1 = 1; \ +volatile ushort2 prefix##_us_2 = 1; \ +volatile ushort3 prefix##_us_3 = 1; \ +volatile ushort4 prefix##_us_4 = 1; \ +volatile int prefix##_i_1 = 1; \ +volatile int2 prefix##_i_2 = 1; \ +volatile int3 prefix##_i_3 = 1; \ +volatile int4 prefix##_i_4 = 1; \ +volatile uint prefix##_ui_1 = 1; \ +volatile uint2 prefix##_ui_2 = 1; \ +volatile uint3 prefix##_ui_3 = 1; \ +volatile uint4 prefix##_ui_4 = 1; \ +volatile long prefix##_l_1 = 1; \ +volatile ulong prefix##_ul_1 = 1; + +DECL_INT(res) +DECL_INT(src1) +DECL_INT(src2) + +#define TEST_INT_OP_TYPE(op, type) \ +rsDebug("Testing " #op " for " #type "3", i++); \ +res_##type##_3 = src1_##type##_3 op src2_##type##_3; \ + +#define TEST_INT_OP(op) \ +TEST_INT_OP_TYPE(op, c) \ +TEST_INT_OP_TYPE(op, uc) \ + +#define TEST_XN_FUNC_YN(typeout, fnc, typein) \ + res_##typeout##_1 = fnc(src1_##typein##_1); \ + res_##typeout##_2 = fnc(src1_##typein##_2); \ + res_##typeout##_3 = fnc(src1_##typein##_3); \ + res_##typeout##_4 = fnc(src1_##typein##_4); + +#define TEST_XN_FUNC_XN_XN(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \ + res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \ + res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \ + res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4); + +#define TEST_X_FUNC_X_X_X(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1); + +#define TEST_IN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, uc) \ + TEST_XN_FUNC_YN(c, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, us) \ + TEST_XN_FUNC_YN(s, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, ui) \ + TEST_XN_FUNC_YN(i, fnc, i) + +#define TEST_UIN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, i) \ + +#define TEST_IN_FUNC_IN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_XN_XN(uc, fnc) \ + TEST_XN_FUNC_XN_XN(c, fnc) \ + TEST_XN_FUNC_XN_XN(us, fnc) \ + TEST_XN_FUNC_XN_XN(s, fnc) \ + TEST_XN_FUNC_XN_XN(ui, fnc) \ + TEST_XN_FUNC_XN_XN(i, fnc) + +#define TEST_I_FUNC_I_I_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_X_FUNC_X_X_X(uc, fnc) \ + TEST_X_FUNC_X_X_X(c, fnc) \ + TEST_X_FUNC_X_X_X(us, fnc) \ + TEST_X_FUNC_X_X_X(s, fnc) \ + TEST_X_FUNC_X_X_X(ui, fnc) \ + TEST_X_FUNC_X_X_X(i, fnc) + +#define TEST_FN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f2 = fnc(f2); \ + f3 = fnc(f3); \ + f4 = fnc(f4); + +#define TEST_FN_FUNC_FN_PFN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (float*) &f1); \ + f2 = fnc(f2, (float2*) &f2); \ + f3 = fnc(f3, (float3*) &f3); \ + f4 = fnc(f4, (float4*) &f4); + +#define TEST_FN_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f2); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_F34_FUNC_F34_F34(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f1); \ + f3 = fnc(f3, f1); \ + f4 = fnc(f4, f1); + +#define TEST_F_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f1 = fnc(f2); \ + f1 = fnc(f3); \ + f1 = fnc(f4); + +#define TEST_F_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f1 = fnc(f2, f2); \ + f1 = fnc(f3, f3); \ + f1 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i2); \ + f3 = fnc(f3, i3); \ + f4 = fnc(f4, i4); + +#define TEST_FN_FUNC_FN_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i1); \ + f3 = fnc(f3, i1); \ + f4 = fnc(f4, i1); + +#define TEST_FN_FUNC_FN_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f2, f2); \ + f3 = fnc(f3, f3, f3); \ + f4 = fnc(f4, f4, f4); + +#define TEST_FN_FUNC_FN_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f1, f1); \ + f3 = fnc(f3, f1, f1); \ + f4 = fnc(f4, f1, f1); + +#define TEST_FN_FUNC_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (int*) &i1); \ + f2 = fnc(f2, (int2*) &i2); \ + f3 = fnc(f3, (int3*) &i3); \ + f4 = fnc(f4, (int4*) &i4); + +#define TEST_FN_FUNC_FN_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, (int*) &i1); \ + f2 = fnc(f2, f2, (int2*) &i2); \ + f3 = fnc(f3, f3, (int3*) &i3); \ + f4 = fnc(f4, f4, (int4*) &i4); + +#define TEST_IN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + i1 = fnc(f1); \ + i2 = fnc(f2); \ + i3 = fnc(f3); \ + i4 = fnc(f4); + +static bool test_fp_math(uint32_t index) { + bool failed = false; + start(); + + TEST_FN_FUNC_FN(acos); + TEST_FN_FUNC_FN(acosh); + TEST_FN_FUNC_FN(acospi); + TEST_FN_FUNC_FN(asin); + TEST_FN_FUNC_FN(asinh); + TEST_FN_FUNC_FN(asinpi); + TEST_FN_FUNC_FN(atan); + TEST_FN_FUNC_FN_FN(atan2); + TEST_FN_FUNC_FN(atanh); + TEST_FN_FUNC_FN(atanpi); + TEST_FN_FUNC_FN_FN(atan2pi); + TEST_FN_FUNC_FN(cbrt); + TEST_FN_FUNC_FN(ceil); + TEST_FN_FUNC_FN_FN_FN(clamp); + TEST_FN_FUNC_FN_FN_F(clamp); + TEST_FN_FUNC_FN_FN(copysign); + TEST_FN_FUNC_FN(cos); + TEST_FN_FUNC_FN(cosh); + TEST_FN_FUNC_FN(cospi); + TEST_F34_FUNC_F34_F34(cross); + TEST_FN_FUNC_FN(degrees); + TEST_F_FUNC_FN_FN(distance); + TEST_F_FUNC_FN_FN(dot); + TEST_FN_FUNC_FN(erfc); + TEST_FN_FUNC_FN(erf); + TEST_FN_FUNC_FN(exp); + TEST_FN_FUNC_FN(exp2); + TEST_FN_FUNC_FN(exp10); + TEST_FN_FUNC_FN(expm1); + TEST_FN_FUNC_FN(fabs); + TEST_FN_FUNC_FN_FN(fdim); + TEST_FN_FUNC_FN(floor); + TEST_FN_FUNC_FN_FN_FN(fma); + TEST_FN_FUNC_FN_FN(fmax); + TEST_FN_FUNC_FN_F(fmax); + TEST_FN_FUNC_FN_FN(fmin); + TEST_FN_FUNC_FN_F(fmin); + TEST_FN_FUNC_FN_FN(fmod); + TEST_FN_FUNC_FN_PFN(fract); + TEST_FN_FUNC_FN_PIN(frexp); + TEST_FN_FUNC_FN_FN(hypot); + TEST_IN_FUNC_FN(ilogb); + TEST_FN_FUNC_FN_IN(ldexp); + TEST_FN_FUNC_FN_I(ldexp); + TEST_F_FUNC_FN(length); + TEST_FN_FUNC_FN(lgamma); + TEST_FN_FUNC_FN_PIN(lgamma); + TEST_FN_FUNC_FN(log); + TEST_FN_FUNC_FN(log2); + TEST_FN_FUNC_FN(log10); + TEST_FN_FUNC_FN(log1p); + TEST_FN_FUNC_FN(logb); + TEST_FN_FUNC_FN_FN_FN(mad); + TEST_FN_FUNC_FN_FN(max); + TEST_FN_FUNC_FN_F(max); + TEST_FN_FUNC_FN_FN(min); + TEST_FN_FUNC_FN_F(min); + TEST_FN_FUNC_FN_FN_FN(mix); + TEST_FN_FUNC_FN_FN_F(mix); + TEST_FN_FUNC_FN_PFN(modf); + // nan + TEST_FN_FUNC_FN_FN(nextafter); + TEST_FN_FUNC_FN(normalize); + TEST_FN_FUNC_FN_FN(pow); + TEST_FN_FUNC_FN_IN(pown); + TEST_FN_FUNC_FN_FN(powr); + TEST_FN_FUNC_FN(radians); + TEST_FN_FUNC_FN_FN(remainder); + TEST_FN_FUNC_FN_FN_PIN(remquo); + TEST_FN_FUNC_FN(rint); + TEST_FN_FUNC_FN_IN(rootn); + TEST_FN_FUNC_FN(round); + TEST_FN_FUNC_FN(rsqrt); + TEST_FN_FUNC_FN(sign); + TEST_FN_FUNC_FN(sin); + TEST_FN_FUNC_FN_PFN(sincos); + TEST_FN_FUNC_FN(sinh); + TEST_FN_FUNC_FN(sinpi); + TEST_FN_FUNC_FN(sqrt); + TEST_FN_FUNC_FN_FN(step); + TEST_FN_FUNC_FN_F(step); + TEST_FN_FUNC_FN(tan); + TEST_FN_FUNC_FN(tanh); + TEST_FN_FUNC_FN(tanpi); + TEST_FN_FUNC_FN(tgamma); + TEST_FN_FUNC_FN(trunc); + + float time = end(index); + + if (failed) { + rsDebug("test_fp_math FAILED", time); + } + else { + rsDebug("test_fp_math PASSED", time); + } + + return failed; +} + +static bool test_int_math(uint32_t index) { + bool failed = false; + start(); + + TEST_UIN_FUNC_IN(abs); + TEST_IN_FUNC_IN(clz); + TEST_IN_FUNC_IN_IN(min); + TEST_IN_FUNC_IN_IN(max); + TEST_I_FUNC_I_I_I(rsClamp); + + float time = end(index); + + if (failed) { + rsDebug("test_int_math FAILED", time); + } + else { + rsDebug("test_int_math PASSED", time); + } + + return failed; +} + +static bool test_basic_operators() { + bool failed = false; + int i = 0; + + TEST_INT_OP(+); + TEST_INT_OP(-); + TEST_INT_OP(*); + TEST_INT_OP(/); + TEST_INT_OP(%); + TEST_INT_OP(<<); + TEST_INT_OP(>>); + + if (failed) { + rsDebug("test_basic_operators FAILED", 0); + } + else { + rsDebug("test_basic_operators PASSED", 0); + } + + return failed; +} + +#define TEST_CVT(to, from, type) \ +rsDebug("Testing convert from " #from " to " #to, 0); \ +to##1 = from##1; \ +to##2 = convert_##type##2(from##2); \ +to##3 = convert_##type##3(from##3); \ +to##4 = convert_##type##4(from##4); + +#define TEST_CVT_MATRIX(to, type) \ +TEST_CVT(to, c, type); \ +TEST_CVT(to, uc, type); \ +TEST_CVT(to, s, type); \ +TEST_CVT(to, us, type); \ +TEST_CVT(to, i, type); \ +TEST_CVT(to, ui, type); \ +TEST_CVT(to, f, type); \ + +static bool test_convert() { + bool failed = false; + + TEST_CVT_MATRIX(c, char); + TEST_CVT_MATRIX(uc, uchar); + TEST_CVT_MATRIX(s, short); + TEST_CVT_MATRIX(us, ushort); + TEST_CVT_MATRIX(i, int); + TEST_CVT_MATRIX(ui, uint); + TEST_CVT_MATRIX(f, float); + + if (failed) { + rsDebug("test_convert FAILED", 0); + } + else { + rsDebug("test_convert PASSED", 0); + } + + return failed; +} + +void math_test(uint32_t index, int test_num) { + bool failed = false; + rsDebug("Here ", 1); + res_uc_3 = src1_uc_3 / src2_uc_3; + rsDebug("Here ", 2); + failed |= test_basic_operators(); + rsDebug("Here ", 3); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.orig b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.orig new file mode 100644 index 0000000..aae29a4 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.orig @@ -0,0 +1,436 @@ +#include "shared.rsh" + +// Testing math library + +volatile float f1; +volatile float2 f2; +volatile float3 f3; +volatile float4 f4; + +volatile int i1; +volatile int2 i2; +volatile int3 i3; +volatile int4 i4; + +volatile uint ui1; +volatile uint2 ui2; +volatile uint3 ui3; +volatile uint4 ui4; + +volatile short s1; +volatile short2 s2; +volatile short3 s3; +volatile short4 s4; + +volatile ushort us1; +volatile ushort2 us2; +volatile ushort3 us3; +volatile ushort4 us4; + +volatile char c1; +volatile char2 c2; +volatile char3 c3; +volatile char4 c4; + +volatile uchar uc1; +volatile uchar2 uc2; +volatile uchar3 uc3; +volatile uchar4 uc4; + +#define DECL_INT(prefix) \ +volatile char prefix##_c_1 = 1; \ +volatile char2 prefix##_c_2 = 1; \ +volatile char3 prefix##_c_3 = 1; \ +volatile char4 prefix##_c_4 = 1; \ +volatile uchar prefix##_uc_1 = 1; \ +volatile uchar2 prefix##_uc_2 = 1; \ +volatile uchar3 prefix##_uc_3 = 1; \ +volatile uchar4 prefix##_uc_4 = 1; \ +volatile short prefix##_s_1 = 1; \ +volatile short2 prefix##_s_2 = 1; \ +volatile short3 prefix##_s_3 = 1; \ +volatile short4 prefix##_s_4 = 1; \ +volatile ushort prefix##_us_1 = 1; \ +volatile ushort2 prefix##_us_2 = 1; \ +volatile ushort3 prefix##_us_3 = 1; \ +volatile ushort4 prefix##_us_4 = 1; \ +volatile int prefix##_i_1 = 1; \ +volatile int2 prefix##_i_2 = 1; \ +volatile int3 prefix##_i_3 = 1; \ +volatile int4 prefix##_i_4 = 1; \ +volatile uint prefix##_ui_1 = 1; \ +volatile uint2 prefix##_ui_2 = 1; \ +volatile uint3 prefix##_ui_3 = 1; \ +volatile uint4 prefix##_ui_4 = 1; \ +volatile long prefix##_l_1 = 1; \ +volatile ulong prefix##_ul_1 = 1; + +DECL_INT(res) +DECL_INT(src1) +DECL_INT(src2) + +#define TEST_INT_OP_TYPE(op, type) \ +rsDebug("Testing " #op " for " #type "1", i++); \ +res_##type##_1 = src1_##type##_1 op src2_##type##_1; \ +rsDebug("Testing " #op " for " #type "2", i++); \ +res_##type##_2 = src1_##type##_2 op src2_##type##_2; \ +rsDebug("Testing " #op " for " #type "3", i++); \ +res_##type##_3 = src1_##type##_3 op src2_##type##_3; \ +rsDebug("Testing " #op " for " #type "4", i++); \ +res_##type##_4 = src1_##type##_4 op src2_##type##_4; + +#define TEST_INT_OP(op) \ +TEST_INT_OP_TYPE(op, c) \ +TEST_INT_OP_TYPE(op, uc) \ +TEST_INT_OP_TYPE(op, s) \ +TEST_INT_OP_TYPE(op, us) \ +TEST_INT_OP_TYPE(op, i) \ +TEST_INT_OP_TYPE(op, ui) \ +rsDebug("Testing " #op " for l1", i++); \ +res_l_1 = src1_l_1 op src2_l_1; \ +rsDebug("Testing " #op " for ul1", i++); \ +res_ul_1 = src1_ul_1 op src2_ul_1; + +#define TEST_XN_FUNC_YN(typeout, fnc, typein) \ + res_##typeout##_1 = fnc(src1_##typein##_1); \ + res_##typeout##_2 = fnc(src1_##typein##_2); \ + res_##typeout##_3 = fnc(src1_##typein##_3); \ + res_##typeout##_4 = fnc(src1_##typein##_4); + +#define TEST_XN_FUNC_XN_XN(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1); \ + res_##type##_2 = fnc(src1_##type##_2, src2_##type##_2); \ + res_##type##_3 = fnc(src1_##type##_3, src2_##type##_3); \ + res_##type##_4 = fnc(src1_##type##_4, src2_##type##_4); + +#define TEST_X_FUNC_X_X_X(type, fnc) \ + res_##type##_1 = fnc(src1_##type##_1, src2_##type##_1, src2_##type##_1); + +#define TEST_IN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, uc) \ + TEST_XN_FUNC_YN(c, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, us) \ + TEST_XN_FUNC_YN(s, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, ui) \ + TEST_XN_FUNC_YN(i, fnc, i) + +#define TEST_UIN_FUNC_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_YN(uc, fnc, c) \ + TEST_XN_FUNC_YN(us, fnc, s) \ + TEST_XN_FUNC_YN(ui, fnc, i) \ + +#define TEST_IN_FUNC_IN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_XN_FUNC_XN_XN(uc, fnc) \ + TEST_XN_FUNC_XN_XN(c, fnc) \ + TEST_XN_FUNC_XN_XN(us, fnc) \ + TEST_XN_FUNC_XN_XN(s, fnc) \ + TEST_XN_FUNC_XN_XN(ui, fnc) \ + TEST_XN_FUNC_XN_XN(i, fnc) + +#define TEST_I_FUNC_I_I_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + TEST_X_FUNC_X_X_X(uc, fnc) \ + TEST_X_FUNC_X_X_X(c, fnc) \ + TEST_X_FUNC_X_X_X(us, fnc) \ + TEST_X_FUNC_X_X_X(s, fnc) \ + TEST_X_FUNC_X_X_X(ui, fnc) \ + TEST_X_FUNC_X_X_X(i, fnc) + +#define TEST_FN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f2 = fnc(f2); \ + f3 = fnc(f3); \ + f4 = fnc(f4); + +#define TEST_FN_FUNC_FN_PFN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (float*) &f1); \ + f2 = fnc(f2, (float2*) &f2); \ + f3 = fnc(f3, (float3*) &f3); \ + f4 = fnc(f4, (float4*) &f4); + +#define TEST_FN_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f2); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_F34_FUNC_F34_F34(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f3 = fnc(f3, f3); \ + f4 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f2 = fnc(f2, f1); \ + f3 = fnc(f3, f1); \ + f4 = fnc(f4, f1); + +#define TEST_F_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f1 = fnc(f2); \ + f1 = fnc(f3); \ + f1 = fnc(f4); + +#define TEST_F_FUNC_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1); \ + f1 = fnc(f2, f2); \ + f1 = fnc(f3, f3); \ + f1 = fnc(f4, f4); + +#define TEST_FN_FUNC_FN_IN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i2); \ + f3 = fnc(f3, i3); \ + f4 = fnc(f4, i4); + +#define TEST_FN_FUNC_FN_I(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i1); \ + f3 = fnc(f3, i1); \ + f4 = fnc(f4, i1); + +#define TEST_FN_FUNC_FN_FN_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f2, f2); \ + f3 = fnc(f3, f3, f3); \ + f4 = fnc(f4, f4, f4); + +#define TEST_FN_FUNC_FN_FN_F(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, f1); \ + f2 = fnc(f2, f1, f1); \ + f3 = fnc(f3, f1, f1); \ + f4 = fnc(f4, f1, f1); + +#define TEST_FN_FUNC_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (int*) &i1); \ + f2 = fnc(f2, (int2*) &i2); \ + f3 = fnc(f3, (int3*) &i3); \ + f4 = fnc(f4, (int4*) &i4); + +#define TEST_FN_FUNC_FN_FN_PIN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, f1, (int*) &i1); \ + f2 = fnc(f2, f2, (int2*) &i2); \ + f3 = fnc(f3, f3, (int3*) &i3); \ + f4 = fnc(f4, f4, (int4*) &i4); + +#define TEST_IN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + i1 = fnc(f1); \ + i2 = fnc(f2); \ + i3 = fnc(f3); \ + i4 = fnc(f4); + +static bool test_fp_math(uint32_t index) { + bool failed = false; + start(); + + TEST_FN_FUNC_FN(acos); + TEST_FN_FUNC_FN(acosh); + TEST_FN_FUNC_FN(acospi); + TEST_FN_FUNC_FN(asin); + TEST_FN_FUNC_FN(asinh); + TEST_FN_FUNC_FN(asinpi); + TEST_FN_FUNC_FN(atan); + TEST_FN_FUNC_FN_FN(atan2); + TEST_FN_FUNC_FN(atanh); + TEST_FN_FUNC_FN(atanpi); + TEST_FN_FUNC_FN_FN(atan2pi); + TEST_FN_FUNC_FN(cbrt); + TEST_FN_FUNC_FN(ceil); + TEST_FN_FUNC_FN_FN_FN(clamp); + TEST_FN_FUNC_FN_FN_F(clamp); + TEST_FN_FUNC_FN_FN(copysign); + TEST_FN_FUNC_FN(cos); + TEST_FN_FUNC_FN(cosh); + TEST_FN_FUNC_FN(cospi); + TEST_F34_FUNC_F34_F34(cross); + TEST_FN_FUNC_FN(degrees); + TEST_F_FUNC_FN_FN(distance); + TEST_F_FUNC_FN_FN(dot); + TEST_FN_FUNC_FN(erfc); + TEST_FN_FUNC_FN(erf); + TEST_FN_FUNC_FN(exp); + TEST_FN_FUNC_FN(exp2); + TEST_FN_FUNC_FN(exp10); + TEST_FN_FUNC_FN(expm1); + TEST_FN_FUNC_FN(fabs); + TEST_FN_FUNC_FN_FN(fdim); + TEST_FN_FUNC_FN(floor); + TEST_FN_FUNC_FN_FN_FN(fma); + TEST_FN_FUNC_FN_FN(fmax); + TEST_FN_FUNC_FN_F(fmax); + TEST_FN_FUNC_FN_FN(fmin); + TEST_FN_FUNC_FN_F(fmin); + TEST_FN_FUNC_FN_FN(fmod); + TEST_FN_FUNC_FN_PFN(fract); + TEST_FN_FUNC_FN_PIN(frexp); + TEST_FN_FUNC_FN_FN(hypot); + TEST_IN_FUNC_FN(ilogb); + TEST_FN_FUNC_FN_IN(ldexp); + TEST_FN_FUNC_FN_I(ldexp); + TEST_F_FUNC_FN(length); + TEST_FN_FUNC_FN(lgamma); + TEST_FN_FUNC_FN_PIN(lgamma); + TEST_FN_FUNC_FN(log); + TEST_FN_FUNC_FN(log2); + TEST_FN_FUNC_FN(log10); + TEST_FN_FUNC_FN(log1p); + TEST_FN_FUNC_FN(logb); + TEST_FN_FUNC_FN_FN_FN(mad); + TEST_FN_FUNC_FN_FN(max); + TEST_FN_FUNC_FN_F(max); + TEST_FN_FUNC_FN_FN(min); + TEST_FN_FUNC_FN_F(min); + TEST_FN_FUNC_FN_FN_FN(mix); + TEST_FN_FUNC_FN_FN_F(mix); + TEST_FN_FUNC_FN_PFN(modf); + // nan + TEST_FN_FUNC_FN_FN(nextafter); + TEST_FN_FUNC_FN(normalize); + TEST_FN_FUNC_FN_FN(pow); + TEST_FN_FUNC_FN_IN(pown); + TEST_FN_FUNC_FN_FN(powr); + TEST_FN_FUNC_FN(radians); + TEST_FN_FUNC_FN_FN(remainder); + TEST_FN_FUNC_FN_FN_PIN(remquo); + TEST_FN_FUNC_FN(rint); + TEST_FN_FUNC_FN_IN(rootn); + TEST_FN_FUNC_FN(round); + TEST_FN_FUNC_FN(rsqrt); + TEST_FN_FUNC_FN(sign); + TEST_FN_FUNC_FN(sin); + TEST_FN_FUNC_FN_PFN(sincos); + TEST_FN_FUNC_FN(sinh); + TEST_FN_FUNC_FN(sinpi); + TEST_FN_FUNC_FN(sqrt); + TEST_FN_FUNC_FN_FN(step); + TEST_FN_FUNC_FN_F(step); + TEST_FN_FUNC_FN(tan); + TEST_FN_FUNC_FN(tanh); + TEST_FN_FUNC_FN(tanpi); + TEST_FN_FUNC_FN(tgamma); + TEST_FN_FUNC_FN(trunc); + + float time = end(index); + + if (failed) { + rsDebug("test_fp_math FAILED", time); + } + else { + rsDebug("test_fp_math PASSED", time); + } + + return failed; +} + +static bool test_int_math(uint32_t index) { + bool failed = false; + start(); + + TEST_UIN_FUNC_IN(abs); + TEST_IN_FUNC_IN(clz); + TEST_IN_FUNC_IN_IN(min); + TEST_IN_FUNC_IN_IN(max); + TEST_I_FUNC_I_I_I(rsClamp); + + float time = end(index); + + if (failed) { + rsDebug("test_int_math FAILED", time); + } + else { + rsDebug("test_int_math PASSED", time); + } + + return failed; +} + +static bool test_basic_operators() { + bool failed = false; + int i = 0; + + TEST_INT_OP(+); + TEST_INT_OP(-); + TEST_INT_OP(*); + TEST_INT_OP(/); + TEST_INT_OP(%); + TEST_INT_OP(<<); + TEST_INT_OP(>>); + + if (failed) { + rsDebug("test_basic_operators FAILED", 0); + } + else { + rsDebug("test_basic_operators PASSED", 0); + } + + return failed; +} + +#define TEST_CVT(to, from, type) \ +rsDebug("Testing convert from " #from " to " #to, 0); \ +to##1 = from##1; \ +to##2 = convert_##type##2(from##2); \ +to##3 = convert_##type##3(from##3); \ +to##4 = convert_##type##4(from##4); + +#define TEST_CVT_MATRIX(to, type) \ +TEST_CVT(to, c, type); \ +TEST_CVT(to, uc, type); \ +TEST_CVT(to, s, type); \ +TEST_CVT(to, us, type); \ +TEST_CVT(to, i, type); \ +TEST_CVT(to, ui, type); \ +TEST_CVT(to, f, type); \ + +static bool test_convert() { + bool failed = false; + + TEST_CVT_MATRIX(c, char); + TEST_CVT_MATRIX(uc, uchar); + TEST_CVT_MATRIX(s, short); + TEST_CVT_MATRIX(us, ushort); + TEST_CVT_MATRIX(i, int); + TEST_CVT_MATRIX(ui, uint); + TEST_CVT_MATRIX(f, float); + + if (failed) { + rsDebug("test_convert FAILED", 0); + } + else { + rsDebug("test_convert PASSED", 0); + } + + return failed; +} + +void math_test(uint32_t index, int test_num) { + bool failed = false; + failed |= test_convert(); + failed |= test_fp_math(index); + failed |= test_int_math(index); + failed |= test_basic_operators(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/primitives.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/primitives.rs new file mode 100644 index 0000000..ce451da --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/primitives.rs @@ -0,0 +1,61 @@ +#include "shared.rsh" + +// Testing primitive types +float floatTest = 1.99f; +double doubleTest = 2.05; +char charTest = -8; +short shortTest = -16; +int intTest = -32; +long longTest = 17179869184l; // 1 << 34 +long long longlongTest = 68719476736l; // 1 << 36 + +uchar ucharTest = 8; +ushort ushortTest = 16; +uint uintTest = 32; +ulong ulongTest = 4611686018427387904L; +int64_t int64_tTest = -17179869184l; // - 1 << 34 +uint64_t uint64_tTest = 117179869184l; + +static bool test_primitive_types(uint32_t index) { + bool failed = false; + start(); + + _RS_ASSERT(floatTest == 2.99f); + _RS_ASSERT(doubleTest == 3.05); + _RS_ASSERT(charTest == -16); + _RS_ASSERT(shortTest == -32); + _RS_ASSERT(intTest == -64); + _RS_ASSERT(longTest == 17179869185l); + _RS_ASSERT(longlongTest == 68719476735l); + + _RS_ASSERT(ucharTest == 8); + _RS_ASSERT(ushortTest == 16); + _RS_ASSERT(uintTest == 32); + _RS_ASSERT(ulongTest == 4611686018427387903L); + _RS_ASSERT(int64_tTest == -17179869184l); + _RS_ASSERT(uint64_tTest == 117179869185l); + + float time = end(index); + + if (failed) { + rsDebug("test_primitives FAILED", time); + } + else { + rsDebug("test_primitives PASSED", time); + } + + return failed; +} + +void primitives_test(uint32_t index, int test_num) { + bool failed = false; + failed |= test_primitive_types(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/refcount.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/refcount.rs new file mode 100644 index 0000000..4ea70e2 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/refcount.rs @@ -0,0 +1,13 @@ +#include "shared.rsh" + +// Testing reference counting of RS object types + +rs_allocation globalA; +static rs_allocation staticGlobalA; + +void refcount_test() { + staticGlobalA = globalA; + rsClearObject(&globalA); + rsSendToClientBlocking(RS_MSG_TEST_PASSED); +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rsdebug.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rsdebug.rs new file mode 100644 index 0000000..f7942a5 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rsdebug.rs @@ -0,0 +1,56 @@ +#include "shared.rsh" + +// Testing primitive types +float floatTest = 1.99f; +double doubleTest = 2.05; +char charTest = -8; +short shortTest = -16; +int intTest = -32; +long longTest = 17179869184l; // 1 << 34 +long long longlongTest = 68719476736l; // 1 << 36 + +uchar ucharTest = 8; +ushort ushortTest = 16; +uint uintTest = 32; +ulong ulongTest = 4611686018427387904L; +int64_t int64_tTest = -17179869184l; // - 1 << 34 +uint64_t uint64_tTest = 117179869184l; + +static bool basic_test(uint32_t index) { + bool failed = false; + + // This test focuses primarily on compilation-time, not run-time. + // For this reason, none of the outputs are actually checked. + + rsDebug("floatTest", floatTest); + rsDebug("doubleTest", doubleTest); + rsDebug("charTest", charTest); + rsDebug("shortTest", shortTest); + rsDebug("intTest", intTest); + rsDebug("longTest", longTest); + rsDebug("longlongTest", longlongTest); + + rsDebug("ucharTest", ucharTest); + rsDebug("ushortTest", ushortTest); + rsDebug("uintTest", uintTest); + rsDebug("ulongTest", ulongTest); + rsDebug("int64_tTest", int64_tTest); + rsDebug("uint64_tTest", uint64_tTest); + + return failed; +} + +void test_rsdebug(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rsdebug_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rsdebug_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rslist.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rslist.rs new file mode 100644 index 0000000..b3d8b9e --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rslist.rs @@ -0,0 +1,107 @@ +// Copyright (C) 2009 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test_v14) + +#include "rs_graphics.rsh" + +float gDY; + +rs_font gFont; + +typedef struct ListAllocs_s { + rs_allocation text; + int result; +} ListAllocs; + +ListAllocs *gList; + +void init() { + gDY = 0.0f; +} + +int textPos = 0; + +int root(void) { + + rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rsgClearDepth(1.0f); + + textPos -= (int)gDY*2; + gDY *= 0.95; + + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFont); + + rs_allocation listAlloc; + listAlloc = rsGetAllocation(gList); + int allocSize = rsAllocationGetDimX(listAlloc); + + int width = rsgGetWidth(); + int height = rsgGetHeight(); + + int itemHeight = 80; + int totalItemHeight = itemHeight * allocSize; + + /* Prevent scrolling above the top of the list */ + int firstItem = height - totalItemHeight; + if (firstItem < 0) { + firstItem = 0; + } + + /* Prevent scrolling past the last line of the list */ + int lastItem = -1 * (totalItemHeight - height); + if (lastItem > 0) { + lastItem = 0; + } + + if (textPos > firstItem) { + textPos = firstItem; + } + else if (textPos < lastItem) { + textPos = lastItem; + } + + int currentYPos = itemHeight + textPos; + + for(int i = 0; i < allocSize; i ++) { + if(currentYPos - itemHeight > height) { + break; + } + + if(currentYPos > 0) { + switch(gList[i].result) { + case 1: /* Passed */ + rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f); + break; + case -1: /* Failed */ + rsgFontColor(0.9f, 0.5f, 0.5f, 1.0f); + break; + case 0: /* Still Testing */ + rsgFontColor(0.9f, 0.9f, 0.5f, 1.0f); + break; + default: /* Unknown */ + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + break; + } + rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0); + rsgDrawText(gList[i].text, 30, currentYPos - 32); + } + currentYPos += itemHeight; + } + + return 10; +} diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstime.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstime.rs new file mode 100644 index 0000000..5e3e078 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstime.rs @@ -0,0 +1,52 @@ +#include "shared.rsh" + +static bool basic_test(uint32_t index) { + bool failed = false; + + rs_time_t curTime = rsTime(0); + rs_tm tm; + rsDebug("curTime", curTime); + + rsLocaltime(&tm, &curTime); + + rsDebug("tm.tm_sec", tm.tm_sec); + rsDebug("tm.tm_min", tm.tm_min); + rsDebug("tm.tm_hour", tm.tm_hour); + rsDebug("tm.tm_mday", tm.tm_mday); + rsDebug("tm.tm_mon", tm.tm_mon); + rsDebug("tm.tm_year", tm.tm_year); + rsDebug("tm.tm_wday", tm.tm_wday); + rsDebug("tm.tm_yday", tm.tm_yday); + rsDebug("tm.tm_isdst", tm.tm_isdst); + + // Test a specific time (only valid for PST localtime) + curTime = 1294438893; + rsLocaltime(&tm, &curTime); + + _RS_ASSERT(tm.tm_sec == 33); + _RS_ASSERT(tm.tm_min == 21); + _RS_ASSERT(tm.tm_hour == 14); + _RS_ASSERT(tm.tm_mday == 7); + _RS_ASSERT(tm.tm_mon == 0); + _RS_ASSERT(tm.tm_year == 111); + _RS_ASSERT(tm.tm_wday == 5); + _RS_ASSERT(tm.tm_yday == 6); + _RS_ASSERT(tm.tm_isdst == 0); + + return failed; +} + +void test_rstime(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rstime_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rstime_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstypes.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstypes.rs new file mode 100644 index 0000000..22d9c13 --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstypes.rs @@ -0,0 +1,79 @@ +#include "shared.rsh" +#include "rs_graphics.rsh" + +rs_element elementTest; +rs_type typeTest; +rs_allocation allocationTest; +rs_sampler samplerTest; +rs_script scriptTest; +rs_mesh meshTest; +rs_program_fragment program_fragmentTest; +rs_program_vertex program_vertexTest; +rs_program_raster program_rasterTest; +rs_program_store program_storeTest; +rs_font fontTest; + +rs_matrix4x4 matrix4x4Test; +rs_matrix3x3 matrix3x3Test; +rs_matrix2x2 matrix2x2Test; + +struct my_struct { + int i; + rs_font fontTestStruct; +}; + +static bool basic_test(uint32_t index) { + bool failed = false; + + rs_matrix4x4 matrix4x4TestLocal; + rs_matrix3x3 matrix3x3TestLocal; + rs_matrix2x2 matrix2x2TestLocal; + + // This test focuses primarily on compilation-time, not run-time. + rs_element elementTestLocal; + rs_type typeTestLocal; + rs_allocation allocationTestLocal; + rs_sampler samplerTestLocal; + rs_script scriptTestLocal; + rs_mesh meshTestLocal; + rs_program_fragment program_fragmentTestLocal; + rs_program_vertex program_vertexTestLocal; + rs_program_raster program_rasterTestLocal; + rs_program_store program_storeTestLocal; + rs_font fontTestLocal; + + rs_font fontTestLocalArray[4]; + + rs_font fontTestLocalPreInit = fontTest; + + struct my_struct structTest; + + fontTestLocal = fontTest; + //allocationTestLocal = allocationTest; + + fontTest = fontTestLocal; + //allocationTest = allocationTestLocal; + + /*for (int i = 0; i < 4; i++) { + fontTestLocalArray[i] = fontTestLocal; + }*/ + + /*fontTest = fontTestLocalArray[3];*/ + + return failed; +} + +void test_rstypes(uint32_t index, int test_num) { + bool failed = false; + failed |= basic_test(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + rsDebug("rstypes_test FAILED", -1); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + rsDebug("rstypes_test PASSED", 0); + } +} + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/shared.rsh b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/shared.rsh new file mode 100644 index 0000000..4a7151f --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/shared.rsh @@ -0,0 +1,38 @@ +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test_v14) + +typedef struct TestResult_s { + rs_allocation name; + bool pass; + float score; + int64_t time; +} TestResult; +//TestResult *g_results; + +static int64_t g_time; + +static void start(void) { + g_time = rsUptimeMillis(); +} + +static float end(uint32_t idx) { + int64_t t = rsUptimeMillis() - g_time; + //g_results[idx].time = t; + //rsDebug("test time", (int)t); + return ((float)t) / 1000.f; +} + +#define _RS_ASSERT(b) \ +do { \ + if (!(b)) { \ + failed = true; \ + rsDebug(#b " FAILED", 0); \ + } \ +\ +} while (0) + +/* These constants must match those in UnitTest.java */ +static const int RS_MSG_TEST_PASSED = 100; +static const int RS_MSG_TEST_FAILED = 101; + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/test_root.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/test_root.rs new file mode 100644 index 0000000..88fe34a --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/test_root.rs @@ -0,0 +1,23 @@ +// Fountain test script +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test_v14) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + + +typedef struct TestResult { + rs_allocation name; + bool pass; + float score; +} TestResult_t; +TestResult_t *results; + +int root() { + + return 0; +} + + diff --git a/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/vector.rs b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/vector.rs new file mode 100644 index 0000000..0430a2f --- /dev/null +++ b/tests/RenderScriptTests/tests_v14/src/com/android/rs/test/vector.rs @@ -0,0 +1,198 @@ +#include "shared.rsh" + +// Testing vector types +float2 f2 = { 1.0f, 2.0f }; +float3 f3 = { 1.0f, 2.0f, 3.0f }; +float4 f4 = { 1.0f, 2.0f, 3.0f, 4.0f }; + +double2 d2 = { 1.0, 2.0 }; +double3 d3 = { 1.0, 2.0, 3.0 }; +double4 d4 = { 1.0, 2.0, 3.0, 4.0 }; + +char2 i8_2 = { 1, 2 }; +char3 i8_3 = { 1, 2, 3 }; +char4 i8_4 = { 1, 2, 3, 4 }; + +uchar2 u8_2 = { 1, 2 }; +uchar3 u8_3 = { 1, 2, 3 }; +uchar4 u8_4 = { 1, 2, 3, 4 }; + +short2 i16_2 = { 1, 2 }; +short3 i16_3 = { 1, 2, 3 }; +short4 i16_4 = { 1, 2, 3, 4 }; + +ushort2 u16_2 = { 1, 2 }; +ushort3 u16_3 = { 1, 2, 3 }; +ushort4 u16_4 = { 1, 2, 3, 4 }; + +int2 i32_2 = { 1, 2 }; +int3 i32_3 = { 1, 2, 3 }; +int4 i32_4 = { 1, 2, 3, 4 }; + +uint2 u32_2 = { 1, 2 }; +uint3 u32_3 = { 1, 2, 3 }; +uint4 u32_4 = { 1, 2, 3, 4 }; + +long2 i64_2 = { 1, 2 }; +long3 i64_3 = { 1, 2, 3 }; +long4 i64_4 = { 1, 2, 3, 4 }; + +ulong2 u64_2 = { 1, 2 }; +ulong3 u64_3 = { 1, 2, 3 }; +ulong4 u64_4 = { 1, 2, 3, 4 }; + +static bool test_vector_types() { + bool failed = false; + + rsDebug("Testing F32", 0); + _RS_ASSERT(f2.x == 2.99f); + _RS_ASSERT(f2.y == 3.99f); + + _RS_ASSERT(f3.x == 2.99f); + _RS_ASSERT(f3.y == 3.99f); + _RS_ASSERT(f3.z == 4.99f); + + _RS_ASSERT(f4.x == 2.99f); + _RS_ASSERT(f4.y == 3.99f); + _RS_ASSERT(f4.z == 4.99f); + _RS_ASSERT(f4.w == 5.99f); + + rsDebug("Testing F64", 0); + _RS_ASSERT(d2.x == 2.99); + _RS_ASSERT(d2.y == 3.99); + + _RS_ASSERT(d3.x == 2.99); + _RS_ASSERT(d3.y == 3.99); + _RS_ASSERT(d3.z == 4.99); + + _RS_ASSERT(d4.x == 2.99); + _RS_ASSERT(d4.y == 3.99); + _RS_ASSERT(d4.z == 4.99); + _RS_ASSERT(d4.w == 5.99); + + rsDebug("Testing I8", 0); + _RS_ASSERT(i8_2.x == 2); + _RS_ASSERT(i8_2.y == 3); + + _RS_ASSERT(i8_3.x == 2); + _RS_ASSERT(i8_3.y == 3); + _RS_ASSERT(i8_3.z == 4); + + _RS_ASSERT(i8_4.x == 2); + _RS_ASSERT(i8_4.y == 3); + _RS_ASSERT(i8_4.z == 4); + _RS_ASSERT(i8_4.w == 5); + + rsDebug("Testing U8", 0); + _RS_ASSERT(u8_2.x == 2); + _RS_ASSERT(u8_2.y == 3); + + _RS_ASSERT(u8_3.x == 2); + _RS_ASSERT(u8_3.y == 3); + _RS_ASSERT(u8_3.z == 4); + + _RS_ASSERT(u8_4.x == 2); + _RS_ASSERT(u8_4.y == 3); + _RS_ASSERT(u8_4.z == 4); + _RS_ASSERT(u8_4.w == 5); + + rsDebug("Testing I16", 0); + _RS_ASSERT(i16_2.x == 2); + _RS_ASSERT(i16_2.y == 3); + + _RS_ASSERT(i16_3.x == 2); + _RS_ASSERT(i16_3.y == 3); + _RS_ASSERT(i16_3.z == 4); + + _RS_ASSERT(i16_4.x == 2); + _RS_ASSERT(i16_4.y == 3); + _RS_ASSERT(i16_4.z == 4); + _RS_ASSERT(i16_4.w == 5); + + rsDebug("Testing U16", 0); + _RS_ASSERT(u16_2.x == 2); + _RS_ASSERT(u16_2.y == 3); + + _RS_ASSERT(u16_3.x == 2); + _RS_ASSERT(u16_3.y == 3); + _RS_ASSERT(u16_3.z == 4); + + _RS_ASSERT(u16_4.x == 2); + _RS_ASSERT(u16_4.y == 3); + _RS_ASSERT(u16_4.z == 4); + _RS_ASSERT(u16_4.w == 5); + + rsDebug("Testing I32", 0); + _RS_ASSERT(i32_2.x == 2); + _RS_ASSERT(i32_2.y == 3); + + _RS_ASSERT(i32_3.x == 2); + _RS_ASSERT(i32_3.y == 3); + _RS_ASSERT(i32_3.z == 4); + + _RS_ASSERT(i32_4.x == 2); + _RS_ASSERT(i32_4.y == 3); + _RS_ASSERT(i32_4.z == 4); + _RS_ASSERT(i32_4.w == 5); + + rsDebug("Testing U32", 0); + _RS_ASSERT(u32_2.x == 2); + _RS_ASSERT(u32_2.y == 3); + + _RS_ASSERT(u32_3.x == 2); + _RS_ASSERT(u32_3.y == 3); + _RS_ASSERT(u32_3.z == 4); + + _RS_ASSERT(u32_4.x == 2); + _RS_ASSERT(u32_4.y == 3); + _RS_ASSERT(u32_4.z == 4); + _RS_ASSERT(u32_4.w == 5); + + rsDebug("Testing I64", 0); + _RS_ASSERT(i64_2.x == 2); + _RS_ASSERT(i64_2.y == 3); + + _RS_ASSERT(i64_3.x == 2); + _RS_ASSERT(i64_3.y == 3); + _RS_ASSERT(i64_3.z == 4); + + _RS_ASSERT(i64_4.x == 2); + _RS_ASSERT(i64_4.y == 3); + _RS_ASSERT(i64_4.z == 4); + _RS_ASSERT(i64_4.w == 5); + + rsDebug("Testing U64", 0); + _RS_ASSERT(u64_2.x == 2); + _RS_ASSERT(u64_2.y == 3); + + _RS_ASSERT(u64_3.x == 2); + _RS_ASSERT(u64_3.y == 3); + _RS_ASSERT(u64_3.z == 4); + + _RS_ASSERT(u64_4.x == 2); + _RS_ASSERT(u64_4.y == 3); + _RS_ASSERT(u64_4.z == 4); + _RS_ASSERT(u64_4.w == 5); + + if (failed) { + rsDebug("test_vector FAILED", 0); + } + else { + rsDebug("test_vector PASSED", 0); + } + + return failed; +} + +void vector_test() { + bool failed = false; + failed |= test_vector_types(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/tests/SerialChat/Android.mk b/tests/SerialChat/Android.mk new file mode 100644 index 0000000..a534e1a --- /dev/null +++ b/tests/SerialChat/Android.mk @@ -0,0 +1,26 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := SerialChat + +include $(BUILD_PACKAGE) diff --git a/tests/SerialChat/AndroidManifest.xml b/tests/SerialChat/AndroidManifest.xml new file mode 100644 index 0000000..0efdb58 --- /dev/null +++ b/tests/SerialChat/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.serialchat"> + + <uses-permission android:name="android.permission.SERIAL_PORT"/> + + <application android:label="Serial Chat"> + <activity android:name="SerialChat" android:label="Serial Chat"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/SerialChat/res/layout/serial_chat.xml b/tests/SerialChat/res/layout/serial_chat.xml new file mode 100644 index 0000000..596ecbf --- /dev/null +++ b/tests/SerialChat/res/layout/serial_chat.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + > + + <ScrollView android:id="@+id/scroll" + android:layout_width="match_parent" + android:layout_height="0px" + android:layout_weight="1" + > + <TextView android:id="@+id/log" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="25dp" + android:textSize="12sp" + android:textColor="#ffffffff" + /> + </ScrollView> + + <EditText android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:capitalize="sentences" + android:autoText="true" + android:singleLine="true" + /> + +</LinearLayout> + + diff --git a/tests/SerialChat/src/com/android/serialchat/SerialChat.java b/tests/SerialChat/src/com/android/serialchat/SerialChat.java new file mode 100644 index 0000000..faec312 --- /dev/null +++ b/tests/SerialChat/src/com/android/serialchat/SerialChat.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.serialchat; + +import android.app.Activity; +import android.content.Context; +import android.hardware.SerialManager; +import android.hardware.SerialPort; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.ParcelFileDescriptor; +import android.view.KeyEvent; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.util.Log; +import android.widget.EditText; +import android.widget.TextView; + +import java.nio.ByteBuffer; +import java.io.IOException; + +public class SerialChat extends Activity implements Runnable, TextView.OnEditorActionListener { + + private static final String TAG = "SerialChat"; + + private TextView mLog; + private EditText mEditText; + private ByteBuffer mInputBuffer; + private ByteBuffer mOutputBuffer; + private SerialManager mSerialManager; + private SerialPort mSerialPort; + private boolean mPermissionRequestPending; + + private static final int MESSAGE_LOG = 1; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mSerialManager = (SerialManager)getSystemService(Context.SERIAL_SERVICE); + setContentView(R.layout.serial_chat); + mLog = (TextView)findViewById(R.id.log); + mEditText = (EditText)findViewById(R.id.message); + mEditText.setOnEditorActionListener(this); + + if (false) { + mInputBuffer = ByteBuffer.allocateDirect(1024); + mOutputBuffer = ByteBuffer.allocateDirect(1024); + } else { + mInputBuffer = ByteBuffer.allocate(1024); + mOutputBuffer = ByteBuffer.allocate(1024); + } + } + + @Override + public void onResume() { + super.onResume(); + + String[] ports = mSerialManager.getSerialPorts(); + if (ports != null && ports.length > 0) { + try { + mSerialPort = mSerialManager.openSerialPort(ports[0], 115200); + if (mSerialPort != null) { + new Thread(this).start(); + } + } catch (IOException e) { + } + } + + } + + @Override + public void onPause() { + super.onPause(); + + } + + @Override + public void onDestroy() { + if (mSerialPort != null) { + try { + mSerialPort.close(); + } catch (IOException e) { + } + mSerialPort = null; + } + super.onDestroy(); + } + + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (/* actionId == EditorInfo.IME_ACTION_DONE && */ mSerialPort != null) { + try { + String text = v.getText().toString(); + Log.d(TAG, "write: " + text); + byte[] bytes = text.getBytes(); + mOutputBuffer.clear(); + mOutputBuffer.put(bytes); + mSerialPort.write(mOutputBuffer, bytes.length); + } catch (IOException e) { + Log.e(TAG, "write failed", e); + } + v.setText(""); + return true; + } + Log.d(TAG, "onEditorAction " + actionId + " event: " + event); + return false; + } + + public void run() { + Log.d(TAG, "run"); + int ret = 0; + byte[] buffer = new byte[1024]; + while (ret >= 0) { + try { + Log.d(TAG, "calling read"); + mInputBuffer.clear(); + ret = mSerialPort.read(mInputBuffer); + Log.d(TAG, "read returned " + ret); + mInputBuffer.get(buffer, 0, ret); + } catch (IOException e) { + Log.e(TAG, "read failed", e); + break; + } + + if (ret > 0) { + Message m = Message.obtain(mHandler, MESSAGE_LOG); + String text = new String(buffer, 0, ret); + Log.d(TAG, "chat: " + text); + m.obj = text; + mHandler.sendMessage(m); + } + } + Log.d(TAG, "thread out"); + } + + Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_LOG: + mLog.setText(mLog.getText() + (String)msg.obj); + break; + } + } + }; +} + + diff --git a/tests/SmokeTest/tests/AndroidManifest.xml b/tests/SmokeTest/tests/AndroidManifest.xml index 517eb1e..cad37c5 100644 --- a/tests/SmokeTest/tests/AndroidManifest.xml +++ b/tests/SmokeTest/tests/AndroidManifest.xml @@ -18,20 +18,30 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.smoketest.tests"> - <!-- We add an application tag here just so that we can indicate that - this package needs to link against the android.test library, - which is needed when building test cases. --> + <!-- + We add an application tag here just so that we can indicate that this package needs to link + against the android.test library, which is needed when building test cases. + --> <application> <uses-library android:name="android.test.runner" /> </application> <!-- - This declares that this app uses the instrumentation test runner targeting - the package of com.android.smoketest. To run the tests use the command: - "adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner" + This declares that this app uses the instrumentation test runner targeting the package of + com.android.smoketest. To run the tests use the command: + `adb shell am instrument -w com.android.smoketest.tests/android.test.InstrumentationTestRunner` --> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.android.smoketest" android:label="System Smoke Tests"/> + <!-- + This declares a method to run the instrumentation with a special runner, which will run each + app as a separate testcase. To do so, use the command: + `adb shell am instrument -w com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner` + --> + <instrumentation android:name="com.android.smoketest.SmokeTestRunner" + android:targetPackage="com.android.smoketest" + android:label="System Smoke Tests"/> + </manifest> diff --git a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java index 5f53a9b..b3a2600 100644 --- a/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java +++ b/tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java @@ -16,15 +16,22 @@ package com.android.smoketest; -import com.android.internal.os.RuntimeInit; - import android.app.ActivityManager; +import android.app.ActivityManager.ProcessErrorStateInfo; import android.content.Context; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.test.AndroidTestCase; import android.util.Log; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Set; /** * This smoke test is designed to quickly sniff for any error conditions @@ -32,72 +39,267 @@ import java.util.List; */ public class ProcessErrorsTest extends AndroidTestCase { - private final String TAG = "ProcessErrorsTest"; - + private static final String TAG = "ProcessErrorsTest"; + + private final Intent mHomeIntent; + protected ActivityManager mActivityManager; + protected PackageManager mPackageManager; + + public ProcessErrorsTest() { + mHomeIntent = new Intent(Intent.ACTION_MAIN); + mHomeIntent.addCategory(Intent.CATEGORY_HOME); + mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } @Override public void setUp() throws Exception { super.setUp(); - mActivityManager = (ActivityManager) + mActivityManager = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE); + mPackageManager = getContext().getPackageManager(); } public void testSetUpConditions() throws Exception { assertNotNull(mActivityManager); + assertNotNull(mPackageManager); } - public void testNoProcessErrors() throws Exception { - List<ActivityManager.ProcessErrorStateInfo> errList; + public void testNoProcessErrorsAfterBoot() throws Exception { + final String reportMsg = checkForProcessErrors(); + if (reportMsg != null) { + Log.w(TAG, reportMsg); + } + + // report a non-empty list back to the test framework + assertNull(reportMsg, reportMsg); + } + + private String checkForProcessErrors() throws Exception { + List<ProcessErrorStateInfo> errList; errList = mActivityManager.getProcessesInErrorState(); - + // note: this contains information about each process that is currently in an error - // condition. if the list is empty (null) then "we're good". - + // condition. if the list is empty (null) then "we're good". + // if the list is non-empty, then it's useful to report the contents of the list - // we'll put a copy in the log, and we'll report it back to the framework via the assert. final String reportMsg = reportListContents(errList); - if (reportMsg != null) { - Log.w(TAG, reportMsg); + return reportMsg; + } + + /** + * A helper function to query the provided {@link PackageManager} for a list of Activities that + * can be launched from Launcher. + */ + static List<ResolveInfo> getLauncherActivities(PackageManager pm) { + final Intent launchable = new Intent(Intent.ACTION_MAIN); + launchable.addCategory(Intent.CATEGORY_LAUNCHER); + final List<ResolveInfo> activities = pm.queryIntentActivities(launchable, 0); + return activities; + } + + /** + * A helper function to create an {@link Intent} to run, given a {@link ResolveInfo} specifying + * an activity to be launched. + */ + static Intent intentForActivity(ResolveInfo app) { + // build an Intent to launch the specified app + final ComponentName component = new ComponentName(app.activityInfo.packageName, + app.activityInfo.name); + final Intent intent = new Intent(Intent.ACTION_MAIN); + intent.setComponent(component); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + return intent; + } + + /** + * A method to run the specified Activity and return a {@link Collection} of the Activities that + * were in an error state, as listed by {@link ActivityManager.getProcessesInErrorState()}. + * <p /> + * The method will launch the app, wait for 7 seconds, check for apps in the error state, send + * the Home intent, wait for 2 seconds, and then return. + */ + public Collection<ProcessError> runOneActivity(ResolveInfo app) { + final long appLaunchWait = 7000; + final long homeLaunchWait = 2000; + + Log.i(TAG, String.format("Running activity %s/%s", app.activityInfo.packageName, + app.activityInfo.name)); + + // We check for any Crash or ANR dialogs that are already up, and we ignore them. This is + // so that we don't report crashes that were caused by prior apps (which those particular + // tests should have caught and reported already). Otherwise, test failures would cascade + // from the initial broken app to many/all of the tests following that app's launch. + final Collection<ProcessError> preErrProcs = + ProcessError.fromCollection(mActivityManager.getProcessesInErrorState()); + + // launch app, and wait 7 seconds for it to start/settle + final Intent intent = intentForActivity(app); + getContext().startActivity(intent); + try { + Thread.sleep(appLaunchWait); + } catch (InterruptedException e) { + // ignore } - - // report a non-empty list back to the test framework - assertNull(reportMsg, errList); + + // Send the "home" intent and wait 2 seconds for us to get there + getContext().startActivity(mHomeIntent); + try { + Thread.sleep(homeLaunchWait); + } catch (InterruptedException e) { + // ignore + } + + // See if there are any errors. We wait until down here to give ANRs as much time as + // possible to occur. + final Collection<ProcessError> errProcs = + ProcessError.fromCollection(mActivityManager.getProcessesInErrorState()); + // Take the difference between the error processes we see now, and the ones that were + // present when we started + if (errProcs != null && preErrProcs != null) { + errProcs.removeAll(preErrProcs); + } + + return errProcs; } - + + /** + * A test that runs all Launcher-launchable activities and verifies that no ANRs or crashes + * happened while doing so. + */ + public void testRunAllActivities() throws Exception { + final Set<ProcessError> errSet = new HashSet<ProcessError>(); + + for (ResolveInfo app : getLauncherActivities(mPackageManager)) { + final Collection<ProcessError> errProcs = runOneActivity(app); + if (errProcs != null) { + errSet.addAll(errProcs); + } + } + + if (!errSet.isEmpty()) { + fail(String.format("Got %d errors:\n%s", errSet.size(), + reportWrappedListContents(errSet))); + } + } + + String reportWrappedListContents(Collection<ProcessError> errList) { + List<ProcessErrorStateInfo> newList = new ArrayList<ProcessErrorStateInfo>(errList.size()); + for (ProcessError err : errList) { + newList.add(err.info); + } + return reportListContents(newList); + } + /** * This helper function will dump the actual error reports. * * @param errList The error report containing one or more error records. * @return Returns a string containing all of the errors. */ - private String reportListContents(List<ActivityManager.ProcessErrorStateInfo> errList) { + private String reportListContents(Collection<ProcessErrorStateInfo> errList) { if (errList == null) return null; StringBuilder builder = new StringBuilder(); - Iterator<ActivityManager.ProcessErrorStateInfo> iter = errList.iterator(); + Iterator<ProcessErrorStateInfo> iter = errList.iterator(); while (iter.hasNext()) { - ActivityManager.ProcessErrorStateInfo entry = iter.next(); + ProcessErrorStateInfo entry = iter.next(); String condition; switch (entry.condition) { case ActivityManager.ProcessErrorStateInfo.CRASHED: - condition = "CRASHED"; + condition = "a CRASH"; break; case ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING: - condition = "ANR"; + condition = "an ANR"; break; default: - condition = "<unknown>"; + condition = "an unknown error"; break; } - builder.append("Process error ").append(condition).append(" "); - builder.append(" ").append(entry.shortMsg); - builder.append(" detected in ").append(entry.processName).append(" ").append(entry.tag); + builder.append(String.format("Process %s encountered %s (%s)", entry.processName, + condition, entry.shortMsg)); + if (entry.condition == ActivityManager.ProcessErrorStateInfo.CRASHED) { + builder.append(String.format(" with stack trace:\n%s\n", entry.stackTrace)); + } + builder.append("\n"); } return builder.toString(); } - + + /** + * A {@link ProcessErrorStateInfo} wrapper class that hashes how we want (so that equivalent + * crashes are considered equal). + */ + static class ProcessError { + public final ProcessErrorStateInfo info; + + public ProcessError(ProcessErrorStateInfo newInfo) { + info = newInfo; + } + + public static Collection<ProcessError> fromCollection(Collection<ProcessErrorStateInfo> in) + { + if (in == null) { + return null; + } + + List<ProcessError> out = new ArrayList<ProcessError>(in.size()); + for (ProcessErrorStateInfo info : in) { + out.add(new ProcessError(info)); + } + return out; + } + + private boolean strEquals(String a, String b) { + if ((a == null) && (b == null)) { + return true; + } else if ((a == null) || (b == null)) { + return false; + } else { + return a.equals(b); + } + } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (!(other instanceof ProcessError)) return false; + ProcessError peOther = (ProcessError) other; + + return (info.condition == peOther.info.condition) + && strEquals(info.longMsg, peOther.info.longMsg) + && (info.pid == peOther.info.pid) + && strEquals(info.processName, peOther.info.processName) + && strEquals(info.shortMsg, peOther.info.shortMsg) + && strEquals(info.stackTrace, peOther.info.stackTrace) + && strEquals(info.tag, peOther.info.tag) + && (info.uid == peOther.info.uid); + } + + private int hash(Object obj) { + if (obj == null) { + return 13; + } else { + return obj.hashCode(); + } + } + + @Override + public int hashCode() { + int code = 17; + code += info.condition; + code *= hash(info.longMsg); + code += info.pid; + code *= hash(info.processName); + code *= hash(info.shortMsg); + code *= hash(info.stackTrace); + code *= hash(info.tag); + code += info.uid; + return code; + } + } } diff --git a/tests/SmokeTest/tests/src/com/android/smoketest/SmokeTestRunner.java b/tests/SmokeTest/tests/src/com/android/smoketest/SmokeTestRunner.java new file mode 100644 index 0000000..51331fe --- /dev/null +++ b/tests/SmokeTest/tests/src/com/android/smoketest/SmokeTestRunner.java @@ -0,0 +1,94 @@ +/* + * 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.smoketest; + +import android.app.ActivityManager; +import android.app.ActivityManager.ProcessErrorStateInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.test.InstrumentationTestRunner; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * A special test runner which does a test-start for each app in a separate testcase + */ +public class SmokeTestRunner extends InstrumentationTestRunner { + + private static final String SUITE_NAME = "Smoke Test Suite"; + + /** + * Returns a single testcase for each app to launch + */ + @Override + public TestSuite getAllTests() { + final TestSuite suite = new TestSuite(SUITE_NAME); + + final PackageManager pm = getTargetContext().getPackageManager(); + final List<ResolveInfo> apps = ProcessErrorsTest.getLauncherActivities(pm); + + // FIXME: figure out some way to control the reported class names for these anonymous + // FIXME: class instances. + + final TestCase setupTest = new ProcessErrorsTest() { + @Override + public void runTest() throws Exception { + testSetUpConditions(); + } + }; + setupTest.setName("testSetUpConditions"); + suite.addTest(setupTest); + + final TestCase postBootTest = new ProcessErrorsTest() { + @Override + public void runTest() throws Exception { + testNoProcessErrorsAfterBoot(); + } + }; + postBootTest.setName("testNoProcessErrorsAfterBoot"); + suite.addTest(postBootTest); + + for (final ResolveInfo app : apps) { + final TestCase appTest = new ProcessErrorsTest() { + @Override + public void runTest() throws Exception { + final Set<ProcessError> errSet = new HashSet<ProcessError>(); + final Collection<ProcessError> errProcs = runOneActivity(app); + if (errProcs != null) { + errSet.addAll(errProcs); + } + + if (!errSet.isEmpty()) { + fail(String.format("Got %d errors:\n%s", errSet.size(), + reportWrappedListContents(errSet))); + } + } + }; + appTest.setName(app.activityInfo.name); + suite.addTest(appTest); + } + + return suite; + } +} + diff --git a/tests/SmokeTestApps/Android.mk b/tests/SmokeTestApps/Android.mk new file mode 100644 index 0000000..3f5f011 --- /dev/null +++ b/tests/SmokeTestApps/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_PACKAGE_NAME := SmokeTestTriggerApps + +include $(BUILD_PACKAGE) + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/SmokeTestApps/AndroidManifest.xml b/tests/SmokeTestApps/AndroidManifest.xml new file mode 100644 index 0000000..0f20107 --- /dev/null +++ b/tests/SmokeTestApps/AndroidManifest.xml @@ -0,0 +1,45 @@ +<?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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.smoketest.triggers"> + + <application android:label="something"> + <activity android:name=".CrashyApp" + android:label="Test Crashy App"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name=".CrashyApp2" + android:label="Test Crashy App2"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name=".UnresponsiveApp" + android:label="Test Unresponsive App"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/tests/SmokeTestApps/README b/tests/SmokeTestApps/README new file mode 100644 index 0000000..04aa366 --- /dev/null +++ b/tests/SmokeTestApps/README @@ -0,0 +1,3 @@ +The apps in this folder are intentionally bad-behaving apps that are intended +to trigger the smoke tests to fail. They are otherwise not useful. + diff --git a/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java new file mode 100644 index 0000000..c11b0f3 --- /dev/null +++ b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java @@ -0,0 +1,37 @@ +/* + * 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.smoketest.triggers; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +public class CrashyApp extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + TextView tv = new TextView(this); + tv.setText("Hello, Crashy Android"); + setContentView(tv); + } + + @Override + public void onResume() { + ((String) null).length(); + } +} diff --git a/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp2.java b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp2.java new file mode 100644 index 0000000..3ef5b2b --- /dev/null +++ b/tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp2.java @@ -0,0 +1,38 @@ +/* + * 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.smoketest.triggers; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +public class CrashyApp2 extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + TextView tv = new TextView(this); + tv.setText("Hello, Other Crashy Android"); + setContentView(tv); + } + + + @Override + public void onResume() { + throw new RuntimeException("Two drums and a cymbal fall off a cliff..."); + } +} diff --git a/tests/SmokeTestApps/src/com/android/smoketest/triggers/UnresponsiveApp.java b/tests/SmokeTestApps/src/com/android/smoketest/triggers/UnresponsiveApp.java new file mode 100644 index 0000000..1291897 --- /dev/null +++ b/tests/SmokeTestApps/src/com/android/smoketest/triggers/UnresponsiveApp.java @@ -0,0 +1,44 @@ +/* + * 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.smoketest.triggers; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +public class UnresponsiveApp extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + TextView tv = new TextView(this); + tv.setText("Hello, Unresponsive Android"); + setContentView(tv); + } + + @Override + public void onResume() { + // Attempt to provoke the ire of the ActivityManager + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // ignore + } + } + } +} diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java index f463a19..ae01c75 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java @@ -765,22 +765,70 @@ public class NotificationTestList extends TestActivity } }, - new Test("System priority notification") { + new Test("PRIORITY_HIGH") { public void run() { Notification n = new Notification.Builder(NotificationTestList.this) - .setSmallIcon(R.drawable.notification1) - .setContentTitle("System priority") + .setSmallIcon(R.drawable.notification5) + .setContentTitle("High priority") .setContentText("This should appear before all others") + .setPriority(Notification.PRIORITY_HIGH) .getNotification(); int[] idOut = new int[1]; try { INotificationManager directLine = mNM.getService(); - directLine.enqueueNotificationWithTagPriority( + directLine.enqueueNotificationWithTag( + getPackageName(), + null, + 100, + n, + idOut); + } catch (android.os.RemoteException ex) { + // oh well + } + } + }, + + new Test("PRIORITY_MAX") { + public void run() { + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.notification9) + .setContentTitle("MAX priority") + .setContentText("This might appear as an intruder alert") + .setPriority(Notification.PRIORITY_MAX) + .getNotification(); + + int[] idOut = new int[1]; + try { + INotificationManager directLine = mNM.getService(); + directLine.enqueueNotificationWithTag( + getPackageName(), + null, + 200, + n, + idOut); + } catch (android.os.RemoteException ex) { + // oh well + } + } + }, + + new Test("PRIORITY_MIN") { + public void run() { + Notification n = new Notification.Builder(NotificationTestList.this) + .setSmallIcon(R.drawable.notification0) + .setContentTitle("MIN priority") + .setContentText("You should not see this") + .setPriority(Notification.PRIORITY_MIN) + .getNotification(); + + int[] idOut = new int[1]; + try { + INotificationManager directLine = mNM.getService(); + directLine.enqueueNotificationWithTag( getPackageName(), null, 1, - StatusBarNotification.PRIORITY_SYSTEM, n, idOut); } catch (android.os.RemoteException ex) { diff --git a/tests/TileBenchmark/Android.mk b/tests/TileBenchmark/Android.mk index 430f0f1..5851113 100644 --- a/tests/TileBenchmark/Android.mk +++ b/tests/TileBenchmark/Android.mk @@ -21,12 +21,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := TileBenchmark -include $(BUILD_PACKAGE) +LOCAL_MODULE_TAGS := tests -################################################## -include $(CLEAR_VARS) - -include $(BUILD_MULTI_PREBUILT) +LOCAL_JAVA_LIBRARIES := android.test.runner -# Use the folloing include to make our test apk. -include $(call all-makefiles-under,$(LOCAL_PATH)) +include $(BUILD_PACKAGE)
\ No newline at end of file diff --git a/tests/TileBenchmark/AndroidManifest.xml b/tests/TileBenchmark/AndroidManifest.xml index ab61a9e..f125c70 100644 --- a/tests/TileBenchmark/AndroidManifest.xml +++ b/tests/TileBenchmark/AndroidManifest.xml @@ -18,5 +18,9 @@ android:label="@string/playback_activity" android:theme="@android:style/Theme.Holo.NoActionBar"> </activity> + <uses-library android:name="android.test.runner" /> </application> + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.test.tilebenchmark" + android:label="Tests for WebView Tiles."/> </manifest> diff --git a/tests/TileBenchmark/res/layout/main.xml b/tests/TileBenchmark/res/layout/main.xml index 577c466..1b39d5d 100644 --- a/tests/TileBenchmark/res/layout/main.xml +++ b/tests/TileBenchmark/res/layout/main.xml @@ -18,46 +18,52 @@ android:layout_width="match_parent" android:layout_height="match_parent" > - <LinearLayout - android:id="@+id/top" - android:layout_width="match_parent" + <HorizontalScrollView + android:id="@+id/horizontalScrollView" + android:layout_width="wrap_content" android:layout_height="wrap_content" > - <Spinner - android:id="@+id/movement" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:prompt="@string/movement_method" - /> - <Spinner - android:id="@+id/velocity" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:gravity="center_horizontal" - android:prompt="@string/desired_scroll_velocity" - /> - <ToggleButton - android:id="@+id/capture" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textOn="@string/capture_stop" - android:textOff="@string/capture_start" - /> - <EditText - android:id="@+id/url" - android:layout_width="0dip" - android:layout_height="wrap_content" - android:inputType="textUri" - android:imeOptions="actionGo" - android:layout_weight="1" - /> - <Button - android:id="@+id/inspect" - android:layout_width="wrap_content" + <LinearLayout + android:id="@+id/top" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/inspect_log" - /> - </LinearLayout> + > + <Spinner + android:id="@+id/movement" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:prompt="@string/movement_method" + /> + <Spinner + android:id="@+id/velocity" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + android:prompt="@string/desired_scroll_velocity" + /> + <ToggleButton + android:id="@+id/capture" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textOn="@string/capture_stop" + android:textOff="@string/capture_start" + /> + <EditText + android:id="@+id/url" + android:layout_width="400dp" + android:layout_height="wrap_content" + android:inputType="textUri" + android:imeOptions="actionGo|flagNoExtractUi" + android:layout_weight="1" + /> + <Button + android:id="@+id/inspect" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/inspect_log" + /> + </LinearLayout> + </HorizontalScrollView> <com.test.tilebenchmark.ProfiledWebView android:id="@+id/web" android:layout_width="match_parent" diff --git a/tests/TileBenchmark/res/values/strings.xml b/tests/TileBenchmark/res/values/strings.xml index 5af52dc..6c7055b 100644 --- a/tests/TileBenchmark/res/values/strings.xml +++ b/tests/TileBenchmark/res/values/strings.xml @@ -49,8 +49,9 @@ <!-- Drop down menu entry - automatically scroll to the end of the page with scrollBy() [CHAR LIMIT=15] --> <string name="movement_auto_scroll">Auto-scroll</string> - <!-- Drop down menu entry - [CHAR LIMIT=15] --> - <string name="movement_auto_fling">Auto-fling</string> + <!-- Drop down menu entry - automatically record for a set time before + stopping [CHAR LIMIT=15] --> + <string name="movement_timed">Timed</string> <!-- Drop down menu entry - manually navigate the page(s), hit 'capture' button [CHAR LIMIT=15] --> <string name="movement_manual">Manual</string> @@ -67,14 +68,21 @@ <!-- 75th percentile - 75% of frames fall below this value [CHAR LIMIT=12] --> <string name="percentile_75">75%ile</string> + <!-- standard deviation [CHAR LIMIT=12] --> + <string name="std_dev">StdDev</string> + <!-- mean [CHAR LIMIT=12] --> + <string name="mean">mean</string> + + + <!-- Frame rate [CHAR LIMIT=15] --> <string name="frames_per_second">Frames/sec</string> <!-- Portion of viewport covered by good tiles [CHAR LIMIT=15] --> <string name="viewport_coverage">Coverage</string> <!-- Milliseconds taken to inval, and re-render the page [CHAR LIMIT=15] --> <string name="render_millis">RenderMillis</string> - <!-- Number of rendering stalls while running the test [CHAR LIMIT=15] --> - <string name="render_stalls">Stalls</string> + <!-- Animation Framerate [CHAR LIMIT=15] --> + <string name="animation_framerate">AnimFramerate</string> <!-- Format string for stat value overlay [CHAR LIMIT=15] --> <string name="format_stat">%4.4f</string> diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java new file mode 100644 index 0000000..6356cc1 --- /dev/null +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.test.tilebenchmark; + +import com.test.tilebenchmark.ProfileActivity.ProfileCallback; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import android.content.res.Resources; +import android.os.Bundle; +import android.os.Environment; +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; +import android.webkit.WebSettings; +import android.widget.Spinner; + +public class PerformanceTest extends + ActivityInstrumentationTestCase2<ProfileActivity> { + + public static class AnimStat { + double aggVal = 0; + double aggSqrVal = 0; + double count = 0; + } + + private class StatAggregator extends PlaybackGraphs { + private HashMap<String, Double> mDataMap = new HashMap<String, Double>(); + private HashMap<String, AnimStat> mAnimDataMap = new HashMap<String, AnimStat>(); + private int mCount = 0; + + + public void aggregate() { + boolean inAnimTests = mAnimTests != null; + Resources resources = mWeb.getResources(); + String animFramerateString = resources.getString(R.string.animation_framerate); + for (Map.Entry<String, Double> e : mSingleStats.entrySet()) { + String name = e.getKey(); + if (inAnimTests) { + if (name.equals(animFramerateString)) { + // in animation testing phase, record animation framerate and aggregate + // stats, differentiating on values of mAnimTestNr and mDoubleBuffering + String fullName = ANIM_TEST_NAMES[mAnimTestNr] + " " + name; + fullName += mDoubleBuffering ? " tiled" : " webkit"; + + if (!mAnimDataMap.containsKey(fullName)) { + mAnimDataMap.put(fullName, new AnimStat()); + } + AnimStat statVals = mAnimDataMap.get(fullName); + statVals.aggVal += e.getValue(); + statVals.aggSqrVal += e.getValue() * e.getValue(); + statVals.count += 1; + } + } else { + double aggVal = mDataMap.containsKey(name) + ? mDataMap.get(name) : 0; + mDataMap.put(name, aggVal + e.getValue()); + } + } + + if (inAnimTests) { + return; + } + + mCount++; + for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { + for (int statIndex = 0; statIndex < Stats.length; statIndex++) { + String metricLabel = resources.getString( + Metrics[metricIndex].getLabelId()); + String statLabel = resources.getString( + Stats[statIndex].getLabelId()); + + String label = metricLabel + " " + statLabel; + double aggVal = mDataMap.containsKey(label) ? mDataMap + .get(label) : 0; + + aggVal += mStats[metricIndex][statIndex]; + mDataMap.put(label, aggVal); + } + } + + } + + // build the final bundle of results + public Bundle getBundle() { + Bundle b = new Bundle(); + int count = (0 == mCount) ? Integer.MAX_VALUE : mCount; + for (Map.Entry<String, Double> e : mDataMap.entrySet()) { + b.putDouble(e.getKey(), e.getValue() / count); + } + + for (Map.Entry<String, AnimStat> e : mAnimDataMap.entrySet()) { + String statName = e.getKey(); + AnimStat statVals = e.getValue(); + + double avg = statVals.aggVal/statVals.count; + double stdDev = Math.sqrt((statVals.aggSqrVal / statVals.count) - avg * avg); + + b.putDouble(statName, avg); + b.putDouble(statName + " STD DEV", stdDev); + } + + return b; + } + } + + ProfileActivity mActivity; + ProfiledWebView mWeb; + Spinner mMovementSpinner; + StatAggregator mStats; + + private static final String LOGTAG = "PerformanceTest"; + private static final String TEST_LOCATION = "webkit/page_cycler"; + private static final String URL_PREFIX = "file://"; + private static final String URL_POSTFIX = "/index.html?skip=true"; + private static final int MAX_ITERATIONS = 4; + private static final String SCROLL_TEST_DIRS[] = { + "alexa25_2011" + }; + private static final String ANIM_TEST_DIRS[] = { + "dhtml" + }; + + public PerformanceTest() { + super(ProfileActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mActivity = getActivity(); + mWeb = (ProfiledWebView) mActivity.findViewById(R.id.web); + mMovementSpinner = (Spinner) mActivity.findViewById(R.id.movement); + mStats = new StatAggregator(); + + // use mStats as a condition variable between the UI thread and + // this(the testing) thread + mActivity.setCallback(new ProfileCallback() { + @Override + public void profileCallback(RunData data) { + mStats.setData(data); + synchronized (mStats) { + mStats.notify(); + } + } + }); + + } + + private boolean loadUrl(final String url) { + try { + Log.d(LOGTAG, "test starting for url " + url); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mWeb.loadUrl(url); + } + }); + synchronized (mStats) { + mStats.wait(); + } + + mStats.aggregate(); + } catch (InterruptedException e) { + e.printStackTrace(); + return false; + } + return true; + } + + private boolean validTest(String nextTest) { + // if testing animations, test must be in mAnimTests + if (mAnimTests == null) + return true; + + for (String test : mAnimTests) { + if (test.equals(nextTest)) { + return true; + } + } + return false; + } + + private boolean runIteration(String[] testDirs) { + File sdFile = Environment.getExternalStorageDirectory(); + for (String testDirName : testDirs) { + File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName); + Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath() + + "', exists=" + testDir.exists()); + + for (File siteDir : testDir.listFiles()) { + if (!siteDir.isDirectory() || !validTest(siteDir.getName())) { + continue; + } + + if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath() + + URL_POSTFIX)) { + return false; + } + } + } + return true; + } + + private boolean runTestDirs(String[] testDirs) { + for (int i = 0; i < MAX_ITERATIONS; i++) + if (!runIteration(testDirs)) { + return false; + } + return true; + } + + private void pushDoubleBuffering() { + getInstrumentation().runOnMainSync(new Runnable() { + public void run() { + mWeb.setDoubleBuffering(mDoubleBuffering); + } + }); + } + + private void setScrollingTestingMode(final boolean scrolled) { + getInstrumentation().runOnMainSync(new Runnable() { + public void run() { + mMovementSpinner.setSelection(scrolled ? 0 : 2); + } + }); + } + + + private String[] mAnimTests = null; + private int mAnimTestNr = -1; + private boolean mDoubleBuffering = true; + private static final String[] ANIM_TEST_NAMES = { + "slow", "fast" + }; + private static final String[][] ANIM_TESTS = { + {"scrolling", "replaceimages", "layers5", "layers1"}, + {"slidingballs", "meter", "slidein", "fadespacing", "colorfade", + "mozilla", "movingtext", "diagball", "zoom", "imageslide"}, + }; + + private boolean checkMedia() { + String state = Environment.getExternalStorageState(); + + if (!Environment.MEDIA_MOUNTED.equals(state) + && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + Log.d(LOGTAG, "ARG Can't access sd card!"); + // Can't read the SD card, fail and die! + getInstrumentation().sendStatus(1, null); + return false; + } + return true; + } + + public void testMetrics() { + setScrollingTestingMode(true); + if (checkMedia() && runTestDirs(SCROLL_TEST_DIRS)) { + getInstrumentation().sendStatus(0, mStats.getBundle()); + } else { + getInstrumentation().sendStatus(1, null); + } + } + + private boolean runAnimationTests() { + for (int doubleBuffer = 0; doubleBuffer <= 1; doubleBuffer++) { + mDoubleBuffering = doubleBuffer == 1; + pushDoubleBuffering(); + for (mAnimTestNr = 0; mAnimTestNr < ANIM_TESTS.length; mAnimTestNr++) { + mAnimTests = ANIM_TESTS[mAnimTestNr]; + if (!runTestDirs(ANIM_TEST_DIRS)) { + return false; + } + } + } + return true; + } + + public void testAnimations() { + // instead of autoscrolling, load each page until either an timer fires, + // or the animation signals complete via javascript + setScrollingTestingMode(false); + + if (checkMedia() && runAnimationTests()) { + getInstrumentation().sendStatus(0, mStats.getBundle()); + } else { + getInstrumentation().sendStatus(1, null); + } + } +} diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java index 9ea90f8..065e86f 100644 --- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java @@ -37,10 +37,10 @@ public class PlaybackGraphs { private static Paint whiteLabels; private static double viewportCoverage(TileData view, TileData tile) { - if (tile.left < view.right - && tile.right >= view.left - && tile.top < view.bottom - && tile.bottom >= view.top) { + if (tile.left < (view.right * view.scale) + && tile.right >= (view.left * view.scale) + && tile.top < (view.bottom * view.scale) + && tile.bottom >= (view.top * view.scale)) { return 1.0f; } return 0.0f; @@ -80,7 +80,7 @@ public class PlaybackGraphs { for (int tileID = 1; tileID < frame.length; tileID++) { TileData data = frame[tileID]; double coverage = viewportCoverage(frame[0], data); - total += coverage * (data.isReady ? 1 : 0); + total += coverage * (data.isReady ? 100 : 0); totalCount += coverage; } if (totalCount == 0) { @@ -91,7 +91,7 @@ public class PlaybackGraphs { @Override public double getMax() { - return 1; + return 100; } @Override @@ -108,6 +108,9 @@ public class PlaybackGraphs { } public static double getPercentile(double sortedValues[], double ratioAbove) { + if (sortedValues.length == 0) + return -1; + double index = ratioAbove * (sortedValues.length - 1); int intIndex = (int) Math.floor(index); if (index == intIndex) { @@ -118,6 +121,31 @@ public class PlaybackGraphs { + sortedValues[intIndex + 1] * (alpha); } + public static double getMean(double sortedValues[]) { + if (sortedValues.length == 0) + return -1; + + double agg = 0; + for (double val : sortedValues) { + agg += val; + } + return agg / sortedValues.length; + } + + public static double getStdDev(double sortedValues[]) { + if (sortedValues.length == 0) + return -1; + + double agg = 0; + double sqrAgg = 0; + for (double val : sortedValues) { + agg += val; + sqrAgg += val*val; + } + double mean = agg / sortedValues.length; + return Math.sqrt((sqrAgg / sortedValues.length) - (mean * mean)); + } + protected static StatGen[] Stats = new StatGen[] { new StatGen() { @Override @@ -149,6 +177,26 @@ public class PlaybackGraphs { public int getLabelId() { return R.string.percentile_75; } + }, new StatGen() { + @Override + public double getValue(double[] sortedValues) { + return getStdDev(sortedValues); + } + + @Override + public int getLabelId() { + return R.string.std_dev; + } + }, new StatGen() { + @Override + public double getValue(double[] sortedValues) { + return getMean(sortedValues); + } + + @Override + public int getLabelId() { + return R.string.mean; + } }, }; @@ -159,40 +207,47 @@ public class PlaybackGraphs { } private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>(); - protected double[][] mStats = new double[Metrics.length][Stats.length]; + protected final double[][] mStats = new double[Metrics.length][Stats.length]; protected HashMap<String, Double> mSingleStats; + private void gatherFrameMetric(int metricIndex, double metricValues[], RunData data) { + // create graph out of rectangles, one per frame + int lastBar = 0; + for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) { + TileData frame[] = data.frames[frameIndex]; + int newBar = (int)((frame[0].top + frame[0].bottom) * frame[0].scale / 2.0f); + + MetricGen s = Metrics[metricIndex]; + double absoluteValue = s.getValue(frame); + double relativeValue = absoluteValue / s.getMax(); + relativeValue = Math.min(1,relativeValue); + relativeValue = Math.max(0,relativeValue); + int rightPos = (int) (-BAR_WIDTH * metricIndex); + int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue)); + + ShapeDrawable graphBar = new ShapeDrawable(); + graphBar.getPaint().setColor(Color.BLUE); + graphBar.setBounds(leftPos, lastBar, rightPos, newBar); + + mShapes.add(graphBar); + metricValues[frameIndex] = absoluteValue; + lastBar = newBar; + } + } + public void setData(RunData data) { mShapes.clear(); double metricValues[] = new double[data.frames.length]; + mSingleStats = data.singleStats; + if (data.frames.length == 0) { return; } for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { - // create graph out of rectangles, one per frame - int lastBar = 0; - for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) { - TileData frame[] = data.frames[frameIndex]; - int newBar = (frame[0].top + frame[0].bottom) / 2; - - MetricGen s = Metrics[metricIndex]; - double absoluteValue = s.getValue(frame); - double relativeValue = absoluteValue / s.getMax(); - relativeValue = Math.min(1,relativeValue); - relativeValue = Math.max(0,relativeValue); - int rightPos = (int) (-BAR_WIDTH * metricIndex); - int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue)); - - ShapeDrawable graphBar = new ShapeDrawable(); - graphBar.getPaint().setColor(Color.BLUE); - graphBar.setBounds(leftPos, lastBar, rightPos, newBar); - - mShapes.add(graphBar); - metricValues[frameIndex] = absoluteValue; - lastBar = newBar; - } + // calculate metric based on list of frames + gatherFrameMetric(metricIndex, metricValues, data); // store aggregate statistics per metric (median, and similar) Arrays.sort(metricValues); @@ -200,8 +255,6 @@ public class PlaybackGraphs { mStats[metricIndex][statIndex] = Stats[statIndex].getValue(metricValues); } - - mSingleStats = data.singleStats; } } diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java index e7a21ad..2e77157 100644 --- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java @@ -22,11 +22,12 @@ import android.content.Context; import android.graphics.Bitmap; import android.os.AsyncTask; import android.os.Bundle; +import android.os.CountDownTimer; +import android.util.Log; import android.util.Pair; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; -import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.AdapterView; @@ -49,6 +50,8 @@ import java.io.ObjectOutputStream; */ public class ProfileActivity extends Activity { + private static final int TIMED_RECORD_MILLIS = 2000; + public interface ProfileCallback { public void profileCallback(RunData data); } @@ -65,6 +68,7 @@ public class ProfileActivity extends Activity { LoggingWebViewClient mLoggingWebViewClient = new LoggingWebViewClient(); AutoLoggingWebViewClient mAutoLoggingWebViewClient = new AutoLoggingWebViewClient(); + TimedLoggingWebViewClient mTimedLoggingWebViewClient = new TimedLoggingWebViewClient(); private enum TestingState { NOT_TESTING, @@ -93,18 +97,18 @@ public class ProfileActivity extends Activity { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String movementStr = parent.getItemAtPosition(position).toString(); - if (movementStr == getResources().getString( - R.string.movement_auto_scroll) - || movementStr == getResources().getString( - R.string.movement_auto_fling)) { + if (movementStr == getResources().getString(R.string.movement_auto_scroll)) { mWeb.setWebViewClient(mAutoLoggingWebViewClient); mCaptureButton.setEnabled(false); mVelocitySpinner.setEnabled(true); - } else if (movementStr == getResources().getString( - R.string.movement_manual)) { + } else if (movementStr == getResources().getString(R.string.movement_manual)) { mWeb.setWebViewClient(mLoggingWebViewClient); mCaptureButton.setEnabled(true); mVelocitySpinner.setEnabled(false); + } else if (movementStr == getResources().getString(R.string.movement_timed)) { + mWeb.setWebViewClient(mTimedLoggingWebViewClient); + mCaptureButton.setEnabled(false); + mVelocitySpinner.setEnabled(false); } } @@ -124,16 +128,46 @@ public class ProfileActivity extends Activity { super.onPageStarted(view, url, favicon); mUrl.setText(url); } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + view.requestFocus(); + ((ProfiledWebView)view).onPageFinished(); + } } private class AutoLoggingWebViewClient extends LoggingWebViewClient { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + startViewProfiling(true); + } @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + setTestingState(TestingState.PRE_TESTING); + } + } + + private class TimedLoggingWebViewClient extends LoggingWebViewClient { + @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); - view.requestFocus(); + startViewProfiling(false); - startViewProfiling(true); + // after a fixed time after page finished, stop testing + new CountDownTimer(TIMED_RECORD_MILLIS, TIMED_RECORD_MILLIS) { + @Override + public void onTick(long millisUntilFinished) { + } + + @Override + public void onFinish() { + mWeb.stopScrollTest(); + } + }.start(); } @Override @@ -178,11 +212,13 @@ public class ProfileActivity extends Activity { mMovementSpinner.setEnabled(false); break; case START_TESTING: + mCaptureButton.setChecked(true); mUrl.setBackgroundResource(R.color.background_start_testing); mInspectButton.setEnabled(false); mMovementSpinner.setEnabled(false); break; case STOP_TESTING: + mCaptureButton.setChecked(false); mUrl.setBackgroundResource(R.color.background_stop_testing); break; case SAVED_TESTING: @@ -195,7 +231,6 @@ public class ProfileActivity extends Activity { /** auto - automatically scroll. */ private void startViewProfiling(boolean auto) { // toggle capture button to indicate capture state to user - mCaptureButton.setChecked(true); mWeb.startScrollTest(mCallback, auto); setTestingState(TestingState.START_TESTING); } @@ -217,7 +252,7 @@ public class ProfileActivity extends Activity { public void profileCallback(RunData data) { new StoreFileTask().execute(new Pair<String, RunData>( TEMP_FILENAME, data)); - mCaptureButton.setChecked(false); + Log.d("ProfileActivity", "stored " + data.frames.length + " frames in file"); setTestingState(TestingState.STOP_TESTING); } }); @@ -245,8 +280,8 @@ public class ProfileActivity extends Activity { // Movement spinner String content[] = { getResources().getString(R.string.movement_auto_scroll), - getResources().getString(R.string.movement_auto_fling), - getResources().getString(R.string.movement_manual) + getResources().getString(R.string.movement_manual), + getResources().getString(R.string.movement_timed) }; adapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_spinner_item, content); @@ -270,12 +305,7 @@ public class ProfileActivity extends Activity { }); // Custom profiling WebView - WebSettings settings = mWeb.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setSupportZoom(true); - settings.setEnableSmoothTransition(true); - settings.setBuiltInZoomControls(true); - settings.setLoadWithOverviewMode(true); + mWeb.init(this); mWeb.setWebViewClient(new LoggingWebViewClient()); // URL text entry diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java index 10802b4..7c03313 100644 --- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java @@ -20,23 +20,32 @@ import android.content.Context; import android.os.CountDownTimer; import android.util.AttributeSet; import android.util.Log; +import android.webkit.WebSettingsClassic; import android.webkit.WebView; +import android.webkit.WebViewClassic; + +import java.util.ArrayList; import com.test.tilebenchmark.ProfileActivity.ProfileCallback; import com.test.tilebenchmark.RunData.TileData; -public class ProfiledWebView extends WebView { +public class ProfiledWebView extends WebView implements WebViewClassic.PageSwapDelegate { + private static final String LOGTAG = "ProfiledWebView"; + private int mSpeed; private boolean mIsTesting = false; private boolean mIsScrolling = false; private ProfileCallback mCallback; private long mContentInvalMillis; - private boolean mHadToBeForced = false; - private int mTestCount = 0; - private static final int LOAD_STALL_MILLIS = 5000; // nr of millis after load, + private static final int LOAD_STALL_MILLIS = 2000; // nr of millis after load, // before test is forced + // ignore anim end events until this many millis after load + private static final long ANIM_SAFETY_THRESHOLD = 200; + private long mLoadTime; + private long mAnimationTime; + public ProfiledWebView(Context context) { super(context); } @@ -54,6 +63,36 @@ public class ProfiledWebView extends WebView { super(context, attrs, defStyle, privateBrowsing); } + private class JavaScriptInterface { + Context mContext; + + /** Instantiate the interface and set the context */ + JavaScriptInterface(Context c) { + mContext = c; + } + + public void animationComplete() { + mAnimationTime = System.currentTimeMillis(); + } + } + + public void init(Context c) { + WebSettingsClassic settings = getWebViewClassic().getSettings(); + settings.setJavaScriptEnabled(true); + settings.setSupportZoom(true); + settings.setEnableSmoothTransition(true); + settings.setBuiltInZoomControls(true); + settings.setLoadWithOverviewMode(true); + settings.setProperty("use_minimal_memory", "false"); // prefetch tiles, as browser does + addJavascriptInterface(new JavaScriptInterface(c), "Android"); + mAnimationTime = 0; + mLoadTime = 0; + } + + public void onPageFinished() { + mLoadTime = System.currentTimeMillis(); + } + @Override protected void onDraw(android.graphics.Canvas canvas) { if (mIsTesting && mIsScrolling) { @@ -73,16 +112,12 @@ public class ProfiledWebView extends WebView { * scrolling, invalidate all content and redraw it, measuring time taken. */ public void startScrollTest(ProfileCallback callback, boolean autoScrolling) { - mIsScrolling = autoScrolling; mCallback = callback; mIsTesting = false; - mContentInvalMillis = System.currentTimeMillis(); - registerPageSwapCallback(); - contentInvalidateAll(); - invalidate(); + mIsScrolling = false; + WebSettingsClassic settings = getWebViewClassic().getSettings(); + settings.setProperty("tree_updates", "0"); - mTestCount++; - final int testCount = mTestCount; if (autoScrolling) { // after a while, force it to start even if the pages haven't swapped @@ -93,81 +128,109 @@ public class ProfiledWebView extends WebView { @Override public void onFinish() { - if (testCount == mTestCount && !mIsTesting) { - mHadToBeForced = true; - Log.d("ProfiledWebView", "num " + testCount - + " forcing a page swap with a scroll..."); - scrollBy(0, 1); - invalidate(); // ensure a redraw so that auto-scrolling can occur - } + // invalidate all content, and kick off redraw + Log.d("ProfiledWebView", + "kicking off test with callback registration, and tile discard..."); + getWebViewClassic().discardAllTextures(); + invalidate(); + mIsScrolling = true; + mContentInvalMillis = System.currentTimeMillis(); } }.start(); + } else { + mIsTesting = true; + getWebViewClassic().tileProfilingStart(); } } /* * Called after the manual contentInvalidateAll, after the tiles have all * been redrawn. + * From PageSwapDelegate. */ @Override - protected void pageSwapCallback(boolean startAnim) { - mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis; - super.pageSwapCallback(startAnim); - Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis - + "millis"); - mIsTesting = true; - invalidate(); // ensure a redraw so that auto-scrolling can occur - tileProfilingStart(); + public void onPageSwapOccurred(boolean startAnim) { + if (!mIsTesting && mIsScrolling) { + // kick off testing + mContentInvalMillis = System.currentTimeMillis() - mContentInvalMillis; + Log.d("ProfiledWebView", "REDRAW TOOK " + mContentInvalMillis + "millis"); + mIsTesting = true; + invalidate(); // ensure a redraw so that auto-scrolling can occur + getWebViewClassic().tileProfilingStart(); + } + } + + private double animFramerate() { + WebSettingsClassic settings = getWebViewClassic().getSettings(); + String updatesString = settings.getProperty("tree_updates"); + int updates = (updatesString == null) ? -1 : Integer.parseInt(updatesString); + + long animationTime; + if (mAnimationTime == 0 || mAnimationTime - mLoadTime < ANIM_SAFETY_THRESHOLD) { + animationTime = System.currentTimeMillis() - mLoadTime; + } else { + animationTime = mAnimationTime - mLoadTime; + } + + return updates * 1000.0 / animationTime; + } + + public void setDoubleBuffering(boolean useDoubleBuffering) { + WebSettingsClassic settings = getWebViewClassic().getSettings(); + settings.setProperty("use_double_buffering", useDoubleBuffering ? "true" : "false"); } /* * Called once the page has stopped scrolling */ public void stopScrollTest() { - tileProfilingStop(); + getWebViewClassic().tileProfilingStop(); mIsTesting = false; if (mCallback == null) { - tileProfilingClear(); + getWebViewClassic().tileProfilingClear(); return; } - RunData data = new RunData(super.tileProfilingNumFrames()); + RunData data = new RunData(getWebViewClassic().tileProfilingNumFrames()); // record the time spent (before scrolling) rendering the page data.singleStats.put(getResources().getString(R.string.render_millis), (double)mContentInvalMillis); - // record if the page render timed out - Log.d("ProfiledWebView", "hadtobeforced = " + mHadToBeForced); - data.singleStats.put(getResources().getString(R.string.render_stalls), - mHadToBeForced ? 1.0 : 0.0); - mHadToBeForced = false; + + // record framerate + double framerate = animFramerate(); + Log.d(LOGTAG, "anim framerate was "+framerate); + data.singleStats.put(getResources().getString(R.string.animation_framerate), + framerate); for (int frame = 0; frame < data.frames.length; frame++) { data.frames[frame] = new TileData[ - tileProfilingNumTilesInFrame(frame)]; + getWebViewClassic().tileProfilingNumTilesInFrame(frame)]; for (int tile = 0; tile < data.frames[frame].length; tile++) { - int left = tileProfilingGetInt(frame, tile, "left"); - int top = tileProfilingGetInt(frame, tile, "top"); - int right = tileProfilingGetInt(frame, tile, "right"); - int bottom = tileProfilingGetInt(frame, tile, "bottom"); + int left = getWebViewClassic().tileProfilingGetInt(frame, tile, "left"); + int top = getWebViewClassic().tileProfilingGetInt(frame, tile, "top"); + int right = getWebViewClassic().tileProfilingGetInt(frame, tile, "right"); + int bottom = getWebViewClassic().tileProfilingGetInt(frame, tile, "bottom"); - boolean isReady = super.tileProfilingGetInt( + boolean isReady = getWebViewClassic().tileProfilingGetInt( frame, tile, "isReady") == 1; - int level = tileProfilingGetInt(frame, tile, "level"); + int level = getWebViewClassic().tileProfilingGetInt(frame, tile, "level"); - float scale = tileProfilingGetFloat(frame, tile, "scale"); + float scale = getWebViewClassic().tileProfilingGetFloat(frame, tile, "scale"); data.frames[frame][tile] = data.new TileData(left, top, right, bottom, isReady, level, scale); } } - tileProfilingClear(); + getWebViewClassic().tileProfilingClear(); mCallback.profileCallback(data); } @Override public void loadUrl(String url) { + mAnimationTime = 0; + mLoadTime = 0; if (!url.startsWith("http://") && !url.startsWith("file://")) { url = "http://" + url; } @@ -177,4 +240,8 @@ public class ProfiledWebView extends WebView { public void setAutoScrollSpeed(int speedInt) { mSpeed = speedInt; } + + public WebViewClassic getWebViewClassic() { + return WebViewClassic.fromWebView(this); + } } diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java index 2da61cc..5e48afd 100644 --- a/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java +++ b/tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java @@ -46,7 +46,8 @@ public class RunData implements Serializable { public String toString() { return "Tile (" + left + "," + top + ")->(" - + right + "," + bottom + ")"; + + right + "," + bottom + ")" + + (isReady ? "ready" : "NOTready") + " at scale " + scale; } } diff --git a/tests/TileBenchmark/tests/Android.mk b/tests/TileBenchmark/tests/Android.mk deleted file mode 100644 index 8b235ec..0000000 --- a/tests/TileBenchmark/tests/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# We only want this apk build for tests. -LOCAL_MODULE_TAGS := tests - -LOCAL_JAVA_LIBRARIES := android.test.runner - -# Include all test java files. -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := TileBenchmarkTests - -LOCAL_INSTRUMENTATION_FOR := TileBenchmark - -include $(BUILD_PACKAGE) diff --git a/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java b/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java deleted file mode 100644 index 6bf6f6b..0000000 --- a/tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.test.tilebenchmark; - -import com.test.tilebenchmark.ProfileActivity.ProfileCallback; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -import android.content.res.Resources; -import android.os.Bundle; -import android.os.Environment; -import android.test.ActivityInstrumentationTestCase2; -import android.util.Log; - -public class PerformanceTest extends - ActivityInstrumentationTestCase2<ProfileActivity> { - - private class StatAggregator extends PlaybackGraphs { - private HashMap<String, Double> mDataMap = new HashMap<String, Double>(); - private int mCount = 0; - - public void aggregate() { - mCount++; - Resources resources = mView.getResources(); - for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { - for (int statIndex = 0; statIndex < Stats.length; statIndex++) { - String metricLabel = resources.getString( - Metrics[metricIndex].getLabelId()); - String statLabel = resources.getString( - Stats[statIndex].getLabelId()); - - String label = metricLabel + " " + statLabel; - double aggVal = mDataMap.containsKey(label) ? mDataMap - .get(label) : 0; - - aggVal += mStats[metricIndex][statIndex]; - mDataMap.put(label, aggVal); - } - } - for (Map.Entry<String, Double> e : mSingleStats.entrySet()) { - double aggVal = mDataMap.containsKey(e.getKey()) - ? mDataMap.get(e.getKey()) : 0; - mDataMap.put(e.getKey(), aggVal + e.getValue()); - } - } - - public Bundle getBundle() { - Bundle b = new Bundle(); - int count = 0 == mCount ? Integer.MAX_VALUE : mCount; - for (Map.Entry<String, Double> e : mDataMap.entrySet()) { - b.putDouble(e.getKey(), e.getValue() / count); - } - return b; - } - } - - ProfileActivity mActivity; - ProfiledWebView mView; - StatAggregator mStats = new StatAggregator(); - - private static final String LOGTAG = "PerformanceTest"; - private static final String TEST_LOCATION = "webkit/page_cycler"; - private static final String URL_PREFIX = "file://"; - private static final String URL_POSTFIX = "/index.html?skip=true"; - private static final int MAX_ITERATIONS = 4; - private static final String TEST_DIRS[] = { - "intl1"//, "alexa_us", "android", "dom", "intl2", "moz", "moz2" - }; - - public PerformanceTest() { - super(ProfileActivity.class); - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mActivity = getActivity(); - mView = (ProfiledWebView) mActivity.findViewById(R.id.web); - } - - private boolean loadUrl(final String url) { - try { - Log.d(LOGTAG, "test starting for url " + url); - mActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - mView.loadUrl(url); - } - }); - synchronized (mStats) { - mStats.wait(); - } - mStats.aggregate(); - } catch (InterruptedException e) { - e.printStackTrace(); - return false; - } - return true; - } - - private boolean runIteration() { - File sdFile = Environment.getExternalStorageDirectory(); - for (String testDirName : TEST_DIRS) { - File testDir = new File(sdFile, TEST_LOCATION + "/" + testDirName); - Log.d(LOGTAG, "Testing dir: '" + testDir.getAbsolutePath() - + "', exists=" + testDir.exists()); - for (File siteDir : testDir.listFiles()) { - if (!siteDir.isDirectory()) - continue; - - if (!loadUrl(URL_PREFIX + siteDir.getAbsolutePath() - + URL_POSTFIX)) { - return false; - } - } - } - return true; - } - - public void testMetrics() { - String state = Environment.getExternalStorageState(); - - if (!Environment.MEDIA_MOUNTED.equals(state) - && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { - Log.d(LOGTAG, "ARG Can't access sd card!"); - // Can't read the SD card, fail and die! - getInstrumentation().sendStatus(1, null); - return; - } - - // use mGraphs as a condition variable between the UI thread and - // this(the testing) thread - mActivity.setCallback(new ProfileCallback() { - @Override - public void profileCallback(RunData data) { - Log.d(LOGTAG, "test completion callback"); - mStats.setData(data); - synchronized (mStats) { - mStats.notify(); - } - } - }); - - for (int i = 0; i < MAX_ITERATIONS; i++) - if (!runIteration()) { - getInstrumentation().sendStatus(1, null); - return; - } - getInstrumentation().sendStatus(0, mStats.getBundle()); - } -} diff --git a/tests/TtsTests/Android.mk b/tests/TtsTests/Android.mk new file mode 100644 index 0000000..e049c90 --- /dev/null +++ b/tests/TtsTests/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_STATIC_JAVA_LIBRARIES := littlemock +LOCAL_JAVA_LIBRARIES := android.test.runner + +LOCAL_PACKAGE_NAME := TtsTests + +include $(BUILD_PACKAGE) diff --git a/tests/TtsTests/AndroidManifest.xml b/tests/TtsTests/AndroidManifest.xml new file mode 100644 index 0000000..b6d5111 --- /dev/null +++ b/tests/TtsTests/AndroidManifest.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright (C) 2011 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.speech.tts"> + <application> + <uses-library android:name="android.test.runner" /> + + + <service android:name=".MockableTextToSpeechService" + android:label="Mockable Text-to-speech Service"> + <intent-filter> + <action android:name="android.intent.action.TTS_SERVICE" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </service> + + <activity android:name=".MockableCheckVoiceData" + android:theme="@android:style/Theme.NoDisplay"> + <intent-filter> + <action android:name="android.speech.tts.engine.CHECK_TTS_DATA" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + </application> + + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.speech.tts" + android:label="Tests for android.speech.tts" /> +</manifest> diff --git a/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java b/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java new file mode 100644 index 0000000..0ab8ed6 --- /dev/null +++ b/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.speech.tts; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.speech.tts.TextToSpeech; + +import java.util.ArrayList; +import java.util.List; + +public class MockableCheckVoiceData extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + MockableTextToSpeechService.IDelegate delegate = + MockableTextToSpeechService.getMocker(); + + ArrayList<String> availableLangs = delegate.getAvailableVoices(); + ArrayList<String> unavailableLangs = delegate.getUnavailableVoices(); + + final Intent returnVal = new Intent(); + + // Returns early. + if (availableLangs == null) { + setResult(TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL, returnVal); + finish(); + return; + } + + returnVal.putStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES, + availableLangs); + + if (unavailableLangs != null && unavailableLangs.size() > 0) { + returnVal.putStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES, + unavailableLangs); + } + + setResult(TextToSpeech.Engine.CHECK_VOICE_DATA_PASS, returnVal); + finish(); + } + +} diff --git a/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java new file mode 100644 index 0000000..20648a4 --- /dev/null +++ b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.speech.tts; + +import android.speech.tts.SynthesisCallback; +import android.speech.tts.SynthesisRequest; +import android.speech.tts.TextToSpeechService; + +import java.util.ArrayList; + +public class MockableTextToSpeechService extends TextToSpeechService { + + private static IDelegate sDelegate; + + public static void setMocker(IDelegate delegate) { + sDelegate = delegate; + } + + static IDelegate getMocker() { + return sDelegate; + } + + @Override + protected int onIsLanguageAvailable(String lang, String country, String variant) { + return sDelegate.onIsLanguageAvailable(lang, country, variant); + } + + @Override + protected String[] onGetLanguage() { + return sDelegate.onGetLanguage(); + } + + @Override + protected int onLoadLanguage(String lang, String country, String variant) { + return sDelegate.onLoadLanguage(lang, country, variant); + } + + @Override + protected void onStop() { + sDelegate.onStop(); + } + + @Override + protected void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback) { + sDelegate.onSynthesizeText(request, callback); + } + + public static interface IDelegate { + int onIsLanguageAvailable(String lang, String country, String variant); + + String[] onGetLanguage(); + + int onLoadLanguage(String lang, String country, String variant); + + void onStop(); + + void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback); + + ArrayList<String> getAvailableVoices(); + + ArrayList<String> getUnavailableVoices(); + } + +} diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java new file mode 100644 index 0000000..b736e9f --- /dev/null +++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.speech.tts; + +import android.speech.tts.SynthesisCallback; +import android.speech.tts.SynthesisRequest; +import android.speech.tts.TextToSpeech; +import android.test.InstrumentationTestCase; + +import com.android.speech.tts.MockableTextToSpeechService.IDelegate; +import com.google.testing.littlemock.ArgumentCaptor; +import com.google.testing.littlemock.Behaviour; +import com.google.testing.littlemock.LittleMock; +import junit.framework.Assert; + +import java.util.Locale; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public class TextToSpeechTests extends InstrumentationTestCase { + private static final String MOCK_ENGINE = "com.android.speech.tts"; + private static final String MOCK_PACKAGE = "com.android.speech.tts.__testpackage__"; + + private TextToSpeech mTts; + + @Override + public void setUp() throws Exception { + IDelegate passThrough = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(passThrough); + + blockingInitAndVerify(MOCK_ENGINE, TextToSpeech.SUCCESS); + assertEquals(MOCK_ENGINE, mTts.getCurrentEngine()); + } + + + @Override + public void tearDown() { + if (mTts != null) { + mTts.shutdown(); + } + } + + public void testEngineInitialized() throws Exception { + // Fail on an engine that doesn't exist. + blockingInitAndVerify("__DOES_NOT_EXIST__", TextToSpeech.ERROR); + + // Also, the "current engine" must be null + assertNull(mTts.getCurrentEngine()); + } + + public void testSetLanguage_delegation() { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the + // service without any caching or intermediate steps. + mTts.setLanguage(new Locale("eng", "USA", "variant")); + LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage( + "eng", "USA", "variant"); + } + + public void testSetLanguage_availableLanguage() throws Exception { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // --------------------------------------------------------- + // Test 2 : Tests that when the language is successfully set + // like above (returns LANG_COUNTRY_AVAILABLE). That the + // request language changes from that point on. + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage( + "eng", "USA", "variant"); + mTts.setLanguage(new Locale("eng", "USA", "variant")); + blockingCallSpeak("foo bar", delegate); + ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor(); + LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(), + LittleMock.<SynthesisCallback>anyObject()); + + assertEquals("eng", req.getValue().getLanguage()); + assertEquals("USA", req.getValue().getCountry()); + assertEquals("", req.getValue().getVariant()); + } + + public void testSetLanguage_unavailableLanguage() throws Exception { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // --------------------------------------------------------- + // TEST 3 : Tests that the language that is set does not change when the + // engine reports it could not load the specified language. + LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when( + delegate).onLoadLanguage("fra", "FRA", ""); + mTts.setLanguage(Locale.FRANCE); + blockingCallSpeak("le fou barre", delegate); + ArgumentCaptor<SynthesisRequest> req2 = LittleMock.createCaptor(); + LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req2.capture(), + LittleMock.<SynthesisCallback>anyObject()); + + // The params are basically unchanged. + assertEquals("eng", req2.getValue().getLanguage()); + assertEquals("USA", req2.getValue().getCountry()); + assertEquals("", req2.getValue().getVariant()); + } + + + public void testGetLanguage_invalidReturnValues() { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // Test1: Simple end to end test. Ensure that bad return values + // are dealt with appropriately. + LittleMock.doReturn(null).when(delegate).onGetLanguage(); + Locale returnVal = mTts.getLanguage(); + assertNull(returnVal); + + + // Bad value 2. An array of length < 3. + LittleMock.doReturn(new String[] {"eng", "usa"}).when(delegate).onGetLanguage(); + returnVal = mTts.getLanguage(); + assertNull(returnVal); + } + + public void testGetLanguage_validReturnValues() { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // A correct value. + LittleMock.doReturn(new String[] {"eng", "usa", ""}).when(delegate).onGetLanguage(); + Locale returnVal = mTts.getLanguage(); + + // Note: This is not the same as Locale.US . Well tough luck for + // being the only component of the entire framework that standardized + // three letter country and language codes. + assertEquals(new Locale("eng", "USA", ""), returnVal); + } + + public void testIsLanguageAvailable() { + IDelegate delegate = LittleMock.mock(IDelegate.class); + MockableTextToSpeechService.setMocker(delegate); + + // Test1: Simple end to end test. + LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when( + delegate).onIsLanguageAvailable("eng", "USA", ""); + + assertEquals(TextToSpeech.LANG_COUNTRY_AVAILABLE, mTts.isLanguageAvailable(Locale.US)); + LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable( + "eng", "USA", ""); + } + + + private void blockingCallSpeak(String speech, IDelegate mock) throws + InterruptedException { + final CountDownLatch latch = new CountDownLatch(1); + doCountDown(latch).when(mock).onSynthesizeText(LittleMock.<SynthesisRequest>anyObject(), + LittleMock.<SynthesisCallback>anyObject()); + mTts.speak(speech, TextToSpeech.QUEUE_ADD, null); + + awaitCountDown(latch, 5, TimeUnit.SECONDS); + } + + private void blockingInitAndVerify(final String engine, int errorCode) throws + InterruptedException { + TextToSpeech.OnInitListener listener = LittleMock.mock( + TextToSpeech.OnInitListener.class); + + final CountDownLatch latch = new CountDownLatch(1); + doCountDown(latch).when(listener).onInit(errorCode); + + mTts = new TextToSpeech(getInstrumentation().getTargetContext(), + listener, engine, MOCK_PACKAGE, false /* use fallback package */); + + awaitCountDown(latch, 5, TimeUnit.SECONDS); + } + + public interface CountDownBehaviour extends Behaviour { + /** Used to mock methods that return a result. */ + Behaviour andReturn(Object result); + } + + public static CountDownBehaviour doCountDown(final CountDownLatch latch) { + return new CountDownBehaviour() { + @Override + public <T> T when(T mock) { + return LittleMock.doAnswer(new Callable<Void>() { + @Override + public Void call() throws Exception { + latch.countDown(); + return null; + } + }).when(mock); + } + + @Override + public Behaviour andReturn(final Object result) { + return new Behaviour() { + @Override + public <T> T when(T mock) { + return LittleMock.doAnswer(new Callable<Object>() { + @Override + public Object call() throws Exception { + latch.countDown(); + return result; + } + }).when(mock); + } + }; + } + }; + } + + public static void awaitCountDown(CountDownLatch latch, long timeout, TimeUnit unit) + throws InterruptedException { + Assert.assertTrue("Waited too long for method call", latch.await(timeout, unit)); + } +} diff --git a/tests/WebViewTests/Android.mk b/tests/WebViewTests/Android.mk new file mode 100644 index 0000000..b118845 --- /dev/null +++ b/tests/WebViewTests/Android.mk @@ -0,0 +1,27 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_JAVA_LIBRARIES := android.test.runner + +LOCAL_PACKAGE_NAME := WebViewTests + +include $(BUILD_PACKAGE) diff --git a/tests/WebViewTests/AndroidManifest.xml b/tests/WebViewTests/AndroidManifest.xml new file mode 100644 index 0000000..8b080c1 --- /dev/null +++ b/tests/WebViewTests/AndroidManifest.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright (C) 2011 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.webviewtests"> + <application> + <uses-library android:name="android.test.runner" /> + <activity android:name="WebViewStubActivity" android:label="WebViewStubActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.TEST" /> + </intent-filter> + </activity> + </application> + + <instrumentation android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.webviewtests" + android:label="Tests for android.webkit.WebView" /> +</manifest> diff --git a/tests/WebViewTests/res/layout/webview_layout.xml b/tests/WebViewTests/res/layout/webview_layout.xml new file mode 100644 index 0000000..d266d21 --- /dev/null +++ b/tests/WebViewTests/res/layout/webview_layout.xml @@ -0,0 +1,25 @@ +<?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="match_parent" + android:layout_height="match_parent"> + + <WebView android:id="@+id/web_page" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</LinearLayout> diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java new file mode 100644 index 0000000..c2bbdf5 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java @@ -0,0 +1,625 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. This class tests that + * we correctly convert JavaScript arrays to Java arrays when passing them to + * the methods of injected Java objects. + * + * The conversions should follow + * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in + * which the implementation differs from the spec are marked with + * LIVECONNECT_COMPLIANCE. + * FIXME: Consider making our implementation more compliant, if it will not + * break backwards-compatibility. See b/4408210. + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayCoercionTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeArrayCoercionTest extends JavaBridgeTestBase { + private class TestObject extends Controller { + private Object mObjectInstance; + private CustomType mCustomTypeInstance; + + private boolean[] mBooleanArray; + private byte[] mByteArray; + private char[] mCharArray; + private short[] mShortArray; + private int[] mIntArray; + private long[] mLongArray; + private float[] mFloatArray; + private double[] mDoubleArray; + private String[] mStringArray; + private Object[] mObjectArray; + private CustomType[] mCustomTypeArray; + + public TestObject() { + mObjectInstance = new Object(); + mCustomTypeInstance = new CustomType(); + } + + public Object getObjectInstance() { + return mObjectInstance; + } + public CustomType getCustomTypeInstance() { + return mCustomTypeInstance; + } + + public synchronized void setBooleanArray(boolean[] x) { + mBooleanArray = x; + notifyResultIsReady(); + } + public synchronized void setByteArray(byte[] x) { + mByteArray = x; + notifyResultIsReady(); + } + public synchronized void setCharArray(char[] x) { + mCharArray = x; + notifyResultIsReady(); + } + public synchronized void setShortArray(short[] x) { + mShortArray = x; + notifyResultIsReady(); + } + public synchronized void setIntArray(int[] x) { + mIntArray = x; + notifyResultIsReady(); + } + public synchronized void setLongArray(long[] x) { + mLongArray = x; + notifyResultIsReady(); + } + public synchronized void setFloatArray(float[] x) { + mFloatArray = x; + notifyResultIsReady(); + } + public synchronized void setDoubleArray(double[] x) { + mDoubleArray = x; + notifyResultIsReady(); + } + public synchronized void setStringArray(String[] x) { + mStringArray = x; + notifyResultIsReady(); + } + public synchronized void setObjectArray(Object[] x) { + mObjectArray = x; + notifyResultIsReady(); + } + public synchronized void setCustomTypeArray(CustomType[] x) { + mCustomTypeArray = x; + notifyResultIsReady(); + } + + public synchronized boolean[] waitForBooleanArray() { + waitForResult(); + return mBooleanArray; + } + public synchronized byte[] waitForByteArray() { + waitForResult(); + return mByteArray; + } + public synchronized char[] waitForCharArray() { + waitForResult(); + return mCharArray; + } + public synchronized short[] waitForShortArray() { + waitForResult(); + return mShortArray; + } + public synchronized int[] waitForIntArray() { + waitForResult(); + return mIntArray; + } + public synchronized long[] waitForLongArray() { + waitForResult(); + return mLongArray; + } + public synchronized float[] waitForFloatArray() { + waitForResult(); + return mFloatArray; + } + public synchronized double[] waitForDoubleArray() { + waitForResult(); + return mDoubleArray; + } + public synchronized String[] waitForStringArray() { + waitForResult(); + return mStringArray; + } + public synchronized Object[] waitForObjectArray() { + waitForResult(); + return mObjectArray; + } + public synchronized CustomType[] waitForCustomTypeArray() { + waitForResult(); + return mCustomTypeArray; + } + } + + // Two custom types used when testing passing objects. + private class CustomType { + } + + private TestObject mTestObject; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestObject = new TestObject(); + setUpWebView(mTestObject, "testObject"); + } + + // Note that all tests use a single element array for simplicity. We test + // multiple elements elsewhere. + + // Test passing an array of JavaScript numbers in the int32 range to a + // method which takes a Java array. + public void testPassNumberInt32() throws Throwable { + executeJavaScript("testObject.setBooleanArray([0]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + // LIVECONNECT_COMPLIANCE: Should convert to boolean. + executeJavaScript("testObject.setBooleanArray([42]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + executeJavaScript("testObject.setByteArray([42]);"); + assertEquals(42, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. + executeJavaScript("testObject.setCharArray([42]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([42]);"); + assertEquals(42, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([42]);"); + assertEquals(42, mTestObject.waitForIntArray()[0]); + + executeJavaScript("testObject.setLongArray([42]);"); + assertEquals(42L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([42]);"); + assertEquals(42.0f, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([42]);"); + assertEquals(42.0, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([42]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. + executeJavaScript("testObject.setStringArray([42]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([42]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript numbers in the double range to a + // method which takes a Java array. + public void testPassNumberDouble() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should convert to boolean. + executeJavaScript("testObject.setBooleanArray([42.1]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + executeJavaScript("testObject.setByteArray([42.1]);"); + assertEquals(42, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. + executeJavaScript("testObject.setCharArray([42.1]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([42.1]);"); + assertEquals(42, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([42.1]);"); + assertEquals(42, mTestObject.waitForIntArray()[0]); + + executeJavaScript("testObject.setLongArray([42.1]);"); + assertEquals(42L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([42.1]);"); + assertEquals(42.1f, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([42.1]);"); + assertEquals(42.1, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([42.1]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. + executeJavaScript("testObject.setStringArray([42.1]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([42.1]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript NaN values to a method which takes a + // Java array. + public void testPassNumberNaN() throws Throwable { + executeJavaScript("testObject.setBooleanArray([Number.NaN]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + executeJavaScript("testObject.setByteArray([Number.NaN]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + executeJavaScript("testObject.setCharArray([Number.NaN]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([Number.NaN]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([Number.NaN]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + executeJavaScript("testObject.setLongArray([Number.NaN]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([Number.NaN]);"); + assertEquals(Float.NaN, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([Number.NaN]);"); + assertEquals(Double.NaN, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([Number.NaN]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. + executeJavaScript("testObject.setStringArray([Number.NaN]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([Number.NaN]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript infinity values to a method which + // takes a Java array. + public void testPassNumberInfinity() throws Throwable { + executeJavaScript("testObject.setBooleanArray([Infinity]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + executeJavaScript("testObject.setByteArray([Infinity]);"); + assertEquals(-1, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. + executeJavaScript("testObject.setCharArray([Infinity]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([Infinity]);"); + assertEquals(-1, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([Infinity]);"); + assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. + executeJavaScript("testObject.setLongArray([Infinity]);"); + assertEquals(-1L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([Infinity]);"); + assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([Infinity]);"); + assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([Infinity]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. + executeJavaScript("testObject.setStringArray([Infinity]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([Infinity]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript boolean values to a method which + // takes a Java array. + public void testPassBoolean() throws Throwable { + executeJavaScript("testObject.setBooleanArray([true]);"); + assertTrue(mTestObject.waitForBooleanArray()[0]); + executeJavaScript("testObject.setBooleanArray([false]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setByteArray([true]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + executeJavaScript("testObject.setByteArray([false]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. + executeJavaScript("testObject.setCharArray([true]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + executeJavaScript("testObject.setCharArray([false]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setShortArray([true]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + executeJavaScript("testObject.setShortArray([false]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setIntArray([true]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + executeJavaScript("testObject.setIntArray([false]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setLongArray([true]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + executeJavaScript("testObject.setLongArray([false]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1.0. + executeJavaScript("testObject.setFloatArray([true]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + executeJavaScript("testObject.setFloatArray([false]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should be 1.0. + executeJavaScript("testObject.setDoubleArray([true]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + executeJavaScript("testObject.setDoubleArray([false]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([true]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should create instances of java.lang.String. + executeJavaScript("testObject.setStringArray([true]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([true]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript strings to a method which takes a + // Java array. + public void testPassString() throws Throwable { + // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. + executeJavaScript("testObject.setBooleanArray([\"+042.10\"]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setByteArray([\"+042.10\"]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. + executeJavaScript("testObject.setCharArray([\"+042.10\"]);"); + assertEquals(0, mTestObject.waitForCharArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setShortArray([\"+042.10\"]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setIntArray([\"+042.10\"]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setLongArray([\"+042.10\"]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setFloatArray([\"+042.10\"]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setDoubleArray([\"+042.10\"]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and create instances of java.lang.Number. + executeJavaScript("testObject.setObjectArray([\"+042.10\"]);"); + assertNull(mTestObject.waitForObjectArray()); + + executeJavaScript("testObject.setStringArray([\"+042.10\"]);"); + assertEquals("+042.10", mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([\"+042.10\"]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript objects to a method which takes a + // Java array. + public void testPassJavaScriptObject() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setBooleanArray([{foo: 42}]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setByteArray([{foo: 42}]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCharArray([{foo: 42}]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setShortArray([{foo: 42}]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setIntArray([{foo: 42}]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setLongArray([{foo: 42}]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setFloatArray([{foo: 42}]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setDoubleArray([{foo: 42}]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setObjectArray([{foo: 42}]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should call toString() on object. + executeJavaScript("testObject.setStringArray([{foo: 42}]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeArray([{foo: 42}]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of Java objects to a method which takes a Java + // array. + public void testPassJavaObject() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setBooleanArray([testObject.getObjectInstance()]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setByteArray([testObject.getObjectInstance()]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCharArray([testObject.getObjectInstance()]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setShortArray([testObject.getObjectInstance()]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setIntArray([testObject.getObjectInstance()]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setLongArray([testObject.getObjectInstance()]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setFloatArray([testObject.getObjectInstance()]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setDoubleArray([testObject.getObjectInstance()]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create an array and pass Java object. + executeJavaScript("testObject.setObjectArray([testObject.getObjectInstance()]);"); + assertNull(mTestObject.waitForObjectArray()); + + // LIVECONNECT_COMPLIANCE: Should call toString() on object. + executeJavaScript("testObject.setStringArray([testObject.getObjectInstance()]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and pass Java object. + executeJavaScript("testObject.setCustomTypeArray([testObject.getObjectInstance()]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + executeJavaScript("testObject.setCustomTypeArray([testObject.getCustomTypeInstance()]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript null values to a method which takes + // a Java array. + public void testPassNull() throws Throwable { + executeJavaScript("testObject.setByteArray([null]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + executeJavaScript("testObject.setCharArray([null]);"); + assertEquals('\u0000', mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([null]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([null]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + executeJavaScript("testObject.setLongArray([null]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([null]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([null]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + executeJavaScript("testObject.setBooleanArray([null]);"); + assertFalse(mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and pass null. + executeJavaScript("testObject.setObjectArray([null]);"); + assertNull(mTestObject.waitForObjectArray()); + + executeJavaScript("testObject.setStringArray([null]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and pass null. + executeJavaScript("testObject.setCustomTypeArray([null]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } + + // Test passing an array of JavaScript undefined values to a method which + // takes a Java array. + public void testPassUndefined() throws Throwable { + executeJavaScript("testObject.setByteArray([undefined]);"); + assertEquals(0, mTestObject.waitForByteArray()[0]); + + executeJavaScript("testObject.setCharArray([undefined]);"); + assertEquals(0, mTestObject.waitForCharArray()[0]); + + executeJavaScript("testObject.setShortArray([undefined]);"); + assertEquals(0, mTestObject.waitForShortArray()[0]); + + executeJavaScript("testObject.setIntArray([undefined]);"); + assertEquals(0, mTestObject.waitForIntArray()[0]); + + executeJavaScript("testObject.setLongArray([undefined]);"); + assertEquals(0L, mTestObject.waitForLongArray()[0]); + + executeJavaScript("testObject.setFloatArray([undefined]);"); + assertEquals(0.0f, mTestObject.waitForFloatArray()[0]); + + executeJavaScript("testObject.setDoubleArray([undefined]);"); + assertEquals(0.0, mTestObject.waitForDoubleArray()[0]); + + executeJavaScript("testObject.setBooleanArray([undefined]);"); + assertEquals(false, mTestObject.waitForBooleanArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and pass null. + executeJavaScript("testObject.setObjectArray([undefined]);"); + assertNull(mTestObject.waitForObjectArray()); + + executeJavaScript("testObject.setStringArray([undefined]);"); + assertNull(mTestObject.waitForStringArray()[0]); + + // LIVECONNECT_COMPLIANCE: Should create array and pass null. + executeJavaScript("testObject.setCustomTypeArray([undefined]);"); + assertNull(mTestObject.waitForCustomTypeArray()); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java new file mode 100644 index 0000000..2fd42a7 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. This class tests the + * general use of arrays. + * + * The conversions should follow + * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in + * which the implementation differs from the spec are marked with + * LIVECONNECT_COMPLIANCE. + * FIXME: Consider making our implementation more compliant, if it will not + * break backwards-compatibility. See b/4408210. + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeArrayTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeArrayTest extends JavaBridgeTestBase { + private class TestObject extends Controller { + private boolean mBooleanValue; + private int mIntValue; + private String mStringValue; + + private int[] mIntArray; + private int[][] mIntIntArray; + + private boolean mWasArrayMethodCalled; + + public synchronized void setBooleanValue(boolean x) { + mBooleanValue = x; + notifyResultIsReady(); + } + public synchronized void setIntValue(int x) { + mIntValue = x; + notifyResultIsReady(); + } + public synchronized void setStringValue(String x) { + mStringValue = x; + notifyResultIsReady(); + } + + public synchronized boolean waitForBooleanValue() { + waitForResult(); + return mBooleanValue; + } + public synchronized int waitForIntValue() { + waitForResult(); + return mIntValue; + } + public synchronized String waitForStringValue() { + waitForResult(); + return mStringValue; + } + + public synchronized void setIntArray(int[] x) { + mIntArray = x; + notifyResultIsReady(); + } + public synchronized void setIntIntArray(int[][] x) { + mIntIntArray = x; + notifyResultIsReady(); + } + + public synchronized int[] waitForIntArray() { + waitForResult(); + return mIntArray; + } + public synchronized int[][] waitForIntIntArray() { + waitForResult(); + return mIntIntArray; + } + + public synchronized int[] arrayMethod() { + mWasArrayMethodCalled = true; + return new int[] {42, 43, 44}; + } + + public synchronized boolean wasArrayMethodCalled() { + return mWasArrayMethodCalled; + } + } + + private TestObject mTestObject; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestObject = new TestObject(); + setUpWebView(mTestObject, "testObject"); + } + + public void testArrayLength() throws Throwable { + executeJavaScript("testObject.setIntArray([42, 43, 44]);"); + int[] result = mTestObject.waitForIntArray(); + assertEquals(3, result.length); + assertEquals(42, result[0]); + assertEquals(43, result[1]); + assertEquals(44, result[2]); + } + + public void testPassNull() throws Throwable { + executeJavaScript("testObject.setIntArray(null);"); + assertNull(mTestObject.waitForIntArray()); + } + + public void testPassUndefined() throws Throwable { + executeJavaScript("testObject.setIntArray(undefined);"); + assertNull(mTestObject.waitForIntArray()); + } + + public void testPassEmptyArray() throws Throwable { + executeJavaScript("testObject.setIntArray([]);"); + assertEquals(0, mTestObject.waitForIntArray().length); + } + + // Note that this requires being able to pass a string from JavaScript to + // Java. + public void testPassArrayToStringMethod() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should call toString() on array. + executeJavaScript("testObject.setStringValue([42, 42, 42]);"); + assertEquals("undefined", mTestObject.waitForStringValue()); + } + + // Note that this requires being able to pass an integer from JavaScript to + // Java. + public void testPassArrayToNonStringNonArrayMethod() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. + executeJavaScript("testObject.setIntValue([42, 42, 42]);"); + assertEquals(0, mTestObject.waitForIntValue()); + } + + public void testPassNonArrayToArrayMethod() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should raise JavaScript exception. + executeJavaScript("testObject.setIntArray(42);"); + assertNull(mTestObject.waitForIntArray()); + } + + public void testObjectWithLengthProperty() throws Throwable { + executeJavaScript("testObject.setIntArray({length: 3, 1: 42});"); + int[] result = mTestObject.waitForIntArray(); + assertEquals(3, result.length); + assertEquals(0, result[0]); + assertEquals(42, result[1]); + assertEquals(0, result[2]); + } + + public void testNonNumericLengthProperty() throws Throwable { + // LIVECONNECT_COMPLIANCE: This should not count as an array, so we + // should raise a JavaScript exception. + executeJavaScript("testObject.setIntArray({length: \"foo\"});"); + assertNull(mTestObject.waitForIntArray()); + } + + public void testLengthOutOfBounds() throws Throwable { + // LIVECONNECT_COMPLIANCE: This should not count as an array, so we + // should raise a JavaScript exception. + executeJavaScript("testObject.setIntArray({length: -1});"); + assertNull(mTestObject.waitForIntArray()); + + // LIVECONNECT_COMPLIANCE: This should not count as an array, so we + // should raise a JavaScript exception. + long length = (long)Integer.MAX_VALUE + 1L; + executeJavaScript("testObject.setIntArray({length: " + length + "});"); + assertNull(mTestObject.waitForIntArray()); + + // LIVECONNECT_COMPLIANCE: This should not count as an array, so we + // should raise a JavaScript exception. + length = (long)Integer.MAX_VALUE + 1L - (long)Integer.MIN_VALUE + 1L; + executeJavaScript("testObject.setIntArray({length: " + length + "});"); + assertNull(mTestObject.waitForIntArray()); + } + + public void testSparseArray() throws Throwable { + executeJavaScript("var x = [42, 43]; x[3] = 45; testObject.setIntArray(x);"); + int[] result = mTestObject.waitForIntArray(); + assertEquals(4, result.length); + assertEquals(42, result[0]); + assertEquals(43, result[1]); + assertEquals(0, result[2]); + assertEquals(45, result[3]); + } + + // Note that this requires being able to pass a boolean from JavaScript to + // Java. + public void testMethodReturningArrayNotCalled() throws Throwable { + // We don't invoke methods which return arrays, but note that no + // exception is raised. + // LIVECONNECT_COMPLIANCE: Should call method and convert result to + // JavaScript array. + executeJavaScript("testObject.setBooleanValue(undefined === testObject.arrayMethod())"); + assertTrue(mTestObject.waitForBooleanValue()); + assertFalse(mTestObject.wasArrayMethodCalled()); + } + + public void testMultiDimensionalArrayMethod() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. + executeJavaScript("testObject.setIntIntArray([ [42, 43], [44, 45] ]);"); + assertNull(mTestObject.waitForIntIntArray()); + } + + public void testPassMultiDimensionalArray() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should handle multi-dimensional arrays. + executeJavaScript("testObject.setIntArray([ [42, 43], [44, 45] ]);"); + int[] result = mTestObject.waitForIntArray(); + assertEquals(2, result.length); + assertEquals(0, result[0]); + assertEquals(0, result[1]); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java new file mode 100644 index 0000000..c9bbb77 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. Tests a number of features including ... + * - The type of injected objects + * - The type of their methods + * - Replacing objects + * - Removing objects + * - Access control + * - Calling methods on returned objects + * - Multiply injected objects + * - Threading + * - Inheritance + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeBasicsTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeBasicsTest extends JavaBridgeTestBase { + private class TestController extends Controller { + private int mIntValue; + private long mLongValue; + private String mStringValue; + private boolean mBooleanValue; + + public synchronized void setIntValue(int x) { + mIntValue = x; + notifyResultIsReady(); + } + public synchronized void setLongValue(long x) { + mLongValue = x; + notifyResultIsReady(); + } + public synchronized void setStringValue(String x) { + mStringValue = x; + notifyResultIsReady(); + } + public synchronized void setBooleanValue(boolean x) { + mBooleanValue = x; + notifyResultIsReady(); + } + + public synchronized int waitForIntValue() { + waitForResult(); + return mIntValue; + } + public synchronized long waitForLongValue() { + waitForResult(); + return mLongValue; + } + public synchronized String waitForStringValue() { + waitForResult(); + return mStringValue; + } + public synchronized boolean waitForBooleanValue() { + waitForResult(); + return mBooleanValue; + } + } + + private static class ObjectWithStaticMethod { + public static String staticMethod() { + return "foo"; + } + } + + TestController mTestController; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestController = new TestController(); + setUpWebView(mTestController, "testController"); + } + + // Note that this requires that we can pass a JavaScript string to Java. + protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { + executeJavaScript("testController.setStringValue(" + script + ");"); + return mTestController.waitForStringValue(); + } + + protected void injectObjectAndReload(final Object object, final String name) throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().addJavascriptInterface(object, name); + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + } + + // Note that this requires that we can pass a JavaScript boolean to Java. + private void assertRaisesException(String script) throws Throwable { + executeJavaScript("try {" + + script + ";" + + " testController.setBooleanValue(false);" + + "} catch (exception) {" + + " testController.setBooleanValue(true);" + + "}"); + assertTrue(mTestController.waitForBooleanValue()); + } + + public void testTypeOfInjectedObject() throws Throwable { + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); + } + + public void testAdditionNotReflectedUntilReload() throws Throwable { + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().addJavascriptInterface(new Object(), "testObject"); + } + }); + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + } + + public void testRemovalNotReflectedUntilReload() throws Throwable { + injectObjectAndReload(new Object(), "testObject"); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().removeJavascriptInterface("testObject"); + } + }); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); + } + + public void testRemoveObjectNotAdded() throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().removeJavascriptInterface("foo"); + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof foo")); + } + + public void testTypeOfMethod() throws Throwable { + assertEquals("function", + executeJavaScriptAndGetStringResult("typeof testController.setStringValue")); + } + + public void testTypeOfInvalidMethod() throws Throwable { + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testController.foo")); + } + + public void testCallingInvalidMethodRaisesException() throws Throwable { + assertRaisesException("testController.foo()"); + } + + // Note that this requires that we can pass a JavaScript string to Java. + public void testTypeOfStaticMethod() throws Throwable { + injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); + executeJavaScript("testController.setStringValue(typeof testObject.staticMethod)"); + assertEquals("function", mTestController.waitForStringValue()); + } + + // Note that this requires that we can pass a JavaScript string to Java. + public void testCallStaticMethod() throws Throwable { + injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); + executeJavaScript("testController.setStringValue(testObject.staticMethod())"); + assertEquals("foo", mTestController.waitForStringValue()); + } + + public void testPrivateMethodNotExposed() throws Throwable { + injectObjectAndReload(new Object() { + private void method() {} + }, "testObject"); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.method")); + } + + public void testReplaceInjectedObject() throws Throwable { + injectObjectAndReload(new Object() { + public void method() { mTestController.setStringValue("object 1"); } + }, "testObject"); + executeJavaScript("testObject.method()"); + assertEquals("object 1", mTestController.waitForStringValue()); + + injectObjectAndReload(new Object() { + public void method() { mTestController.setStringValue("object 2"); } + }, "testObject"); + executeJavaScript("testObject.method()"); + assertEquals("object 2", mTestController.waitForStringValue()); + } + + public void testInjectNullObjectIsIgnored() throws Throwable { + injectObjectAndReload(null, "testObject"); + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject")); + } + + public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwable { + injectObjectAndReload(new Object(), "testObject"); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + injectObjectAndReload(null, "testObject"); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testObject")); + } + + public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable { + injectObjectAndReload(new Object() { + public void method() { mTestController.setStringValue("0 args"); } + public void method(int x) { mTestController.setStringValue("1 arg"); } + public void method(int x, int y) { mTestController.setStringValue("2 args"); } + }, "testObject"); + executeJavaScript("testObject.method()"); + assertEquals("0 args", mTestController.waitForStringValue()); + executeJavaScript("testObject.method(42)"); + assertEquals("1 arg", mTestController.waitForStringValue()); + executeJavaScript("testObject.method(null)"); + assertEquals("1 arg", mTestController.waitForStringValue()); + executeJavaScript("testObject.method(undefined)"); + assertEquals("1 arg", mTestController.waitForStringValue()); + executeJavaScript("testObject.method(42, 42)"); + assertEquals("2 args", mTestController.waitForStringValue()); + } + + public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable { + assertRaisesException("testController.setIntValue()"); + assertRaisesException("testController.setIntValue(42, 42)"); + } + + public void testObjectPersistsAcrossPageLoads() throws Throwable { + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + assertEquals("object", executeJavaScriptAndGetStringResult("typeof testController")); + } + + public void testSameObjectInjectedMultipleTimes() throws Throwable { + class TestObject { + private int mNumMethodInvocations; + public void method() { mTestController.setIntValue(++mNumMethodInvocations); } + } + final TestObject testObject = new TestObject(); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().addJavascriptInterface(testObject, "testObject1"); + getWebView().addJavascriptInterface(testObject, "testObject2"); + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + executeJavaScript("testObject1.method()"); + assertEquals(1, mTestController.waitForIntValue()); + executeJavaScript("testObject2.method()"); + assertEquals(2, mTestController.waitForIntValue()); + } + + public void testCallMethodOnReturnedObject() throws Throwable { + injectObjectAndReload(new Object() { + public Object getInnerObject() { + return new Object() { + public void method(int x) { mTestController.setIntValue(x); } + }; + } + }, "testObject"); + executeJavaScript("testObject.getInnerObject().method(42)"); + assertEquals(42, mTestController.waitForIntValue()); + } + + public void testReturnedObjectInjectedElsewhere() throws Throwable { + class InnerObject { + private int mNumMethodInvocations; + public void method() { mTestController.setIntValue(++mNumMethodInvocations); } + } + final InnerObject innerObject = new InnerObject(); + final Object object = new Object() { + public InnerObject getInnerObject() { + return innerObject; + } + }; + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().addJavascriptInterface(object, "testObject"); + getWebView().addJavascriptInterface(innerObject, "innerObject"); + getWebView().reload(); + } + }); + mWebViewClient.waitForOnPageFinished(); + executeJavaScript("testObject.getInnerObject().method()"); + assertEquals(1, mTestController.waitForIntValue()); + executeJavaScript("innerObject.method()"); + assertEquals(2, mTestController.waitForIntValue()); + } + + public void testMethodInvokedOnBackgroundThread() throws Throwable { + injectObjectAndReload(new Object() { + public void captureThreadId() { + mTestController.setLongValue(Thread.currentThread().getId()); + } + }, "testObject"); + executeJavaScript("testObject.captureThreadId()"); + final long threadId = mTestController.waitForLongValue(); + assertFalse(threadId == Thread.currentThread().getId()); + runTestOnUiThread(new Runnable() { + @Override + public void run() { + assertFalse(threadId == Thread.currentThread().getId()); + } + }); + } + + public void testPublicInheritedMethod() throws Throwable { + class Base { + public void method(int x) { mTestController.setIntValue(x); } + } + class Derived extends Base { + } + injectObjectAndReload(new Derived(), "testObject"); + assertEquals("function", executeJavaScriptAndGetStringResult("typeof testObject.method")); + executeJavaScript("testObject.method(42)"); + assertEquals(42, mTestController.waitForIntValue()); + } + + public void testPrivateInheritedMethod() throws Throwable { + class Base { + private void method() {} + } + class Derived extends Base { + } + injectObjectAndReload(new Derived(), "testObject"); + assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof testObject.method")); + } + + public void testOverriddenMethod() throws Throwable { + class Base { + public void method() { mTestController.setStringValue("base"); } + } + class Derived extends Base { + public void method() { mTestController.setStringValue("derived"); } + } + injectObjectAndReload(new Derived(), "testObject"); + executeJavaScript("testObject.method()"); + assertEquals("derived", mTestController.waitForStringValue()); + } + + public void testEnumerateMembers() throws Throwable { + injectObjectAndReload(new Object() { + public void method() {} + private void privateMethod() {} + public int field; + private int privateField; + }, "testObject"); + executeJavaScript( + "var result = \"\"; " + + "for (x in testObject) { result += \" \" + x } " + + "testController.setStringValue(result);"); + // LIVECONNECT_COMPLIANCE: Should be able to enumerate members. + assertEquals("", mTestController.waitForStringValue()); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java new file mode 100644 index 0000000..a0f78a4 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java @@ -0,0 +1,646 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. This class tests that + * we correctly convert JavaScript values to Java values when passing them to + * the methods of injected Java objects. + * + * The conversions should follow + * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in + * which the implementation differs from the spec are marked with + * LIVECONNECT_COMPLIANCE. + * FIXME: Consider making our implementation more compliant, if it will not + * break backwards-compatibility. See b/4408210. + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeCoercionTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeCoercionTest extends JavaBridgeTestBase { + private class TestObject extends Controller { + private Object objectInstance; + private CustomType customTypeInstance; + private CustomType2 customType2Instance; + + private boolean mBooleanValue; + private byte mByteValue; + private char mCharValue; + private short mShortValue; + private int mIntValue; + private long mLongValue; + private float mFloatValue; + private double mDoubleValue; + private String mStringValue; + private Object mObjectValue; + private CustomType mCustomTypeValue; + + public TestObject() { + objectInstance = new Object(); + customTypeInstance = new CustomType(); + customType2Instance = new CustomType2(); + } + + public Object getObjectInstance() { + return objectInstance; + } + public CustomType getCustomTypeInstance() { + return customTypeInstance; + } + public CustomType2 getCustomType2Instance() { + return customType2Instance; + } + + public synchronized void setBooleanValue(boolean x) { + mBooleanValue = x; + notifyResultIsReady(); + } + public synchronized void setByteValue(byte x) { + mByteValue = x; + notifyResultIsReady(); + } + public synchronized void setCharValue(char x) { + mCharValue = x; + notifyResultIsReady(); + } + public synchronized void setShortValue(short x) { + mShortValue = x; + notifyResultIsReady(); + } + public synchronized void setIntValue(int x) { + mIntValue = x; + notifyResultIsReady(); + } + public synchronized void setLongValue(long x) { + mLongValue = x; + notifyResultIsReady(); + } + public synchronized void setFloatValue(float x) { + mFloatValue = x; + notifyResultIsReady(); + } + public synchronized void setDoubleValue(double x) { + mDoubleValue = x; + notifyResultIsReady(); + } + public synchronized void setStringValue(String x) { + mStringValue = x; + notifyResultIsReady(); + } + public synchronized void setObjectValue(Object x) { + mObjectValue = x; + notifyResultIsReady(); + } + public synchronized void setCustomTypeValue(CustomType x) { + mCustomTypeValue = x; + notifyResultIsReady(); + } + + public synchronized boolean waitForBooleanValue() { + waitForResult(); + return mBooleanValue; + } + public synchronized byte waitForByteValue() { + waitForResult(); + return mByteValue; + } + public synchronized char waitForCharValue() { + waitForResult(); + return mCharValue; + } + public synchronized short waitForShortValue() { + waitForResult(); + return mShortValue; + } + public synchronized int waitForIntValue() { + waitForResult(); + return mIntValue; + } + public synchronized long waitForLongValue() { + waitForResult(); + return mLongValue; + } + public synchronized float waitForFloatValue() { + waitForResult(); + return mFloatValue; + } + public synchronized double waitForDoubleValue() { + waitForResult(); + return mDoubleValue; + } + public synchronized String waitForStringValue() { + waitForResult(); + return mStringValue; + } + public synchronized Object waitForObjectValue() { + waitForResult(); + return mObjectValue; + } + public synchronized CustomType waitForCustomTypeValue() { + waitForResult(); + return mCustomTypeValue; + } + } + + // Two custom types used when testing passing objects. + private static class CustomType { + } + private static class CustomType2 { + } + + private TestObject mTestObject; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestObject = new TestObject(); + setUpWebView(mTestObject, "testObject"); + } + + // Test passing a JavaScript number in the int32 range to a method of an + // injected object. + public void testPassNumberInt32() throws Throwable { + executeJavaScript("testObject.setByteValue(42);"); + assertEquals(42, mTestObject.waitForByteValue()); + executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42);"); + assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. + executeJavaScript("testObject.setCharValue(42);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(42);"); + assertEquals(42, mTestObject.waitForShortValue()); + executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42);"); + assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(42);"); + assertEquals(42, mTestObject.waitForIntValue()); + + executeJavaScript("testObject.setLongValue(42);"); + assertEquals(42L, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(42);"); + assertEquals(42.0f, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(42);"); + assertEquals(42.0, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. + executeJavaScript("testObject.setObjectValue(42);"); + assertNull(mTestObject.waitForObjectValue()); + + // The spec allows the JS engine flexibility in how to format the number. + executeJavaScript("testObject.setStringValue(42);"); + String str = mTestObject.waitForStringValue(); + assertTrue("42".equals(str) || "42.0".equals(str)); + + executeJavaScript("testObject.setBooleanValue(0);"); + assertFalse(mTestObject.waitForBooleanValue()); + // LIVECONNECT_COMPLIANCE: Should be true; + executeJavaScript("testObject.setBooleanValue(42);"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(42);"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing a JavaScript number in the double range to a method of an + // injected object. + public void testPassNumberDouble() throws Throwable { + executeJavaScript("testObject.setByteValue(42.1);"); + assertEquals(42, mTestObject.waitForByteValue()); + executeJavaScript("testObject.setByteValue(" + Byte.MAX_VALUE + " + 42.1);"); + assertEquals(Byte.MIN_VALUE + 42 - 1, mTestObject.waitForByteValue()); + executeJavaScript("testObject.setByteValue(" + Integer.MAX_VALUE + " + 42.1);"); + assertEquals(-1, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value. + executeJavaScript("testObject.setCharValue(42.1);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(42.1);"); + assertEquals(42, mTestObject.waitForShortValue()); + executeJavaScript("testObject.setShortValue(" + Short.MAX_VALUE + " + 42.1);"); + assertEquals(Short.MIN_VALUE + 42 - 1, mTestObject.waitForShortValue()); + executeJavaScript("testObject.setShortValue(" + Integer.MAX_VALUE + " + 42.1);"); + assertEquals(-1, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(42.1);"); + assertEquals(42, mTestObject.waitForIntValue()); + executeJavaScript("testObject.setIntValue(" + Integer.MAX_VALUE + " + 42.1);"); + assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); + + executeJavaScript("testObject.setLongValue(42.1);"); + assertEquals(42L, mTestObject.waitForLongValue()); + // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. + executeJavaScript("testObject.setLongValue(" + Long.MAX_VALUE + " + 42.1);"); + assertEquals(Long.MIN_VALUE, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(42.1);"); + assertEquals(42.1f, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(42.1);"); + assertEquals(42.1, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. + executeJavaScript("testObject.setObjectValue(42.1);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setStringValue(42.1);"); + assertEquals("42.1", mTestObject.waitForStringValue()); + + executeJavaScript("testObject.setBooleanValue(0.0);"); + assertFalse(mTestObject.waitForBooleanValue()); + // LIVECONNECT_COMPLIANCE: Should be true. + executeJavaScript("testObject.setBooleanValue(42.1);"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(42.1);"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing JavaScript NaN to a method of an injected object. + public void testPassNumberNaN() throws Throwable { + executeJavaScript("testObject.setByteValue(Number.NaN);"); + assertEquals(0, mTestObject.waitForByteValue()); + + executeJavaScript("testObject.setCharValue(Number.NaN);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(Number.NaN);"); + assertEquals(0, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(Number.NaN);"); + assertEquals(0, mTestObject.waitForIntValue()); + + executeJavaScript("testObject.setLongValue(Number.NaN);"); + assertEquals(0L, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(Number.NaN);"); + assertEquals(Float.NaN, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(Number.NaN);"); + assertEquals(Double.NaN, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. + executeJavaScript("testObject.setObjectValue(Number.NaN);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setStringValue(Number.NaN);"); + assertEquals("NaN", mTestObject.waitForStringValue()); + + executeJavaScript("testObject.setBooleanValue(Number.NaN);"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(Number.NaN);"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing JavaScript infinity to a method of an injected object. + public void testPassNumberInfinity() throws Throwable { + executeJavaScript("testObject.setByteValue(Infinity);"); + assertEquals(-1, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should convert to maximum numeric char value. + executeJavaScript("testObject.setCharValue(Infinity);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(Infinity);"); + assertEquals(-1, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(Infinity);"); + assertEquals(Integer.MAX_VALUE, mTestObject.waitForIntValue()); + + // LIVECONNECT_COMPLIANCE: Should be Long.MAX_VALUE. + executeJavaScript("testObject.setLongValue(Infinity);"); + assertEquals(-1L, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(Infinity);"); + assertEquals(Float.POSITIVE_INFINITY, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(Infinity);"); + assertEquals(Double.POSITIVE_INFINITY, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Number. + executeJavaScript("testObject.setObjectValue(Infinity);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setStringValue(Infinity);"); + assertEquals("Inf", mTestObject.waitForStringValue()); + + executeJavaScript("testObject.setBooleanValue(Infinity);"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(Infinity);"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing a JavaScript boolean to a method of an injected object. + public void testPassBoolean() throws Throwable { + executeJavaScript("testObject.setBooleanValue(true);"); + assertTrue(mTestObject.waitForBooleanValue()); + executeJavaScript("testObject.setBooleanValue(false);"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.Boolean. + executeJavaScript("testObject.setObjectValue(true);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setStringValue(false);"); + assertEquals("false", mTestObject.waitForStringValue()); + executeJavaScript("testObject.setStringValue(true);"); + assertEquals("true", mTestObject.waitForStringValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setByteValue(true);"); + assertEquals(0, mTestObject.waitForByteValue()); + executeJavaScript("testObject.setByteValue(false);"); + assertEquals(0, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should convert to numeric char value 1. + executeJavaScript("testObject.setCharValue(true);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + executeJavaScript("testObject.setCharValue(false);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setShortValue(true);"); + assertEquals(0, mTestObject.waitForShortValue()); + executeJavaScript("testObject.setShortValue(false);"); + assertEquals(0, mTestObject.waitForShortValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setIntValue(true);"); + assertEquals(0, mTestObject.waitForIntValue()); + executeJavaScript("testObject.setIntValue(false);"); + assertEquals(0, mTestObject.waitForIntValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1. + executeJavaScript("testObject.setLongValue(true);"); + assertEquals(0L, mTestObject.waitForLongValue()); + executeJavaScript("testObject.setLongValue(false);"); + assertEquals(0L, mTestObject.waitForLongValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1.0. + executeJavaScript("testObject.setFloatValue(true);"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + executeJavaScript("testObject.setFloatValue(false);"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + // LIVECONNECT_COMPLIANCE: Should be 1.0. + executeJavaScript("testObject.setDoubleValue(true);"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + executeJavaScript("testObject.setDoubleValue(false);"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(true);"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing a JavaScript string to a method of an injected object. + public void testPassString() throws Throwable { + executeJavaScript("testObject.setStringValue(\"+042.10\");"); + assertEquals("+042.10", mTestObject.waitForStringValue()); + + // Make sure that we distinguish between the empty string and NULL. + executeJavaScript("testObject.setStringValue(\"\");"); + assertEquals("", mTestObject.waitForStringValue()); + + // LIVECONNECT_COMPLIANCE: Should create an instance of java.lang.String. + executeJavaScript("testObject.setObjectValue(\"+042.10\");"); + assertNull(mTestObject.waitForObjectValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setByteValue(\"+042.10\");"); + assertEquals(0, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setShortValue(\"+042.10\");"); + assertEquals(0, mTestObject.waitForShortValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setIntValue(\"+042.10\");"); + assertEquals(0, mTestObject.waitForIntValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setLongValue(\"+042.10\");"); + assertEquals(0L, mTestObject.waitForLongValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setFloatValue(\"+042.10\");"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + // LIVECONNECT_COMPLIANCE: Should use valueOf() of appropriate type. + executeJavaScript("testObject.setDoubleValue(\"+042.10\");"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should decode and convert to numeric char value. + executeJavaScript("testObject.setCharValue(\"+042.10\");"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + // LIVECONNECT_COMPLIANCE: Non-empty string should convert to true. + executeJavaScript("testObject.setBooleanValue(\"+042.10\");"); + assertFalse(mTestObject.waitForBooleanValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue(\"+042.10\");"); + assertNull(mTestObject.waitForCustomTypeValue()); + } + + // Test passing a JavaScript object to a method of an injected object. + public void testPassJavaScriptObject() throws Throwable { + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setObjectValue({foo: 42});"); + assertNull(mTestObject.waitForObjectValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCustomTypeValue({foo: 42});"); + assertNull(mTestObject.waitForCustomTypeValue()); + + // LIVECONNECT_COMPLIANCE: Should call toString() on object. + executeJavaScript("testObject.setStringValue({foo: 42});"); + assertEquals("undefined", mTestObject.waitForStringValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setByteValue({foo: 42});"); + assertEquals(0, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCharValue({foo: 42});"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setShortValue({foo: 42});"); + assertEquals(0, mTestObject.waitForShortValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setIntValue({foo: 42});"); + assertEquals(0, mTestObject.waitForIntValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setLongValue({foo: 42});"); + assertEquals(0L, mTestObject.waitForLongValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setFloatValue({foo: 42});"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setDoubleValue({foo: 42});"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setBooleanValue({foo: 42});"); + assertFalse(mTestObject.waitForBooleanValue()); + } + + // Test passing a Java object to a method of an injected object. Note that + // this test requires being able to return objects from the methods of + // injected objects. This is tested elsewhere. + public void testPassJavaObject() throws Throwable { + executeJavaScript("testObject.setObjectValue(testObject.getObjectInstance());"); + assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForObjectValue()); + executeJavaScript("testObject.setObjectValue(testObject.getCustomTypeInstance());"); + assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setCustomTypeValue(testObject.getObjectInstance());"); + assertTrue(mTestObject.getObjectInstance() == mTestObject.waitForCustomTypeValue()); + executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomTypeInstance());"); + assertTrue(mTestObject.getCustomTypeInstance() == mTestObject.waitForCustomTypeValue()); + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception, as the types are unrelated. + executeJavaScript("testObject.setCustomTypeValue(testObject.getCustomType2Instance());"); + assertTrue(mTestObject.getCustomType2Instance() == + (Object)mTestObject.waitForCustomTypeValue()); + + // LIVECONNECT_COMPLIANCE: Should call toString() on object. + executeJavaScript("testObject.setStringValue(testObject.getObjectInstance());"); + assertEquals("undefined", mTestObject.waitForStringValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setByteValue(testObject.getObjectInstance());"); + assertEquals(0, mTestObject.waitForByteValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setCharValue(testObject.getObjectInstance());"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setShortValue(testObject.getObjectInstance());"); + assertEquals(0, mTestObject.waitForShortValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setIntValue(testObject.getObjectInstance());"); + assertEquals(0, mTestObject.waitForIntValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setLongValue(testObject.getObjectInstance());"); + assertEquals(0L, mTestObject.waitForLongValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setFloatValue(testObject.getObjectInstance());"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setDoubleValue(testObject.getObjectInstance());"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + // LIVECONNECT_COMPLIANCE: Should raise a JavaScript exception. + executeJavaScript("testObject.setBooleanValue(testObject.getObjectInstance());"); + assertFalse(mTestObject.waitForBooleanValue()); + } + + // Test passing JavaScript null to a method of an injected object. + public void testPassNull() throws Throwable { + executeJavaScript("testObject.setObjectValue(null);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setCustomTypeValue(null);"); + assertNull(mTestObject.waitForCustomTypeValue()); + + executeJavaScript("testObject.setStringValue(null);"); + assertNull(mTestObject.waitForStringValue()); + + executeJavaScript("testObject.setByteValue(null);"); + assertEquals(0, mTestObject.waitForByteValue()); + + executeJavaScript("testObject.setCharValue(null);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(null);"); + assertEquals(0, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(null);"); + assertEquals(0, mTestObject.waitForIntValue()); + + executeJavaScript("testObject.setLongValue(null);"); + assertEquals(0L, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(null);"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(null);"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + executeJavaScript("testObject.setBooleanValue(null);"); + assertFalse(mTestObject.waitForBooleanValue()); + } + + // Test passing JavaScript undefined to a method of an injected object. + public void testPassUndefined() throws Throwable { + executeJavaScript("testObject.setObjectValue(undefined);"); + assertNull(mTestObject.waitForObjectValue()); + + executeJavaScript("testObject.setCustomTypeValue(undefined);"); + assertNull(mTestObject.waitForCustomTypeValue()); + + // LIVECONNECT_COMPLIANCE: Should be NULL. + executeJavaScript("testObject.setStringValue(undefined);"); + assertEquals("undefined", mTestObject.waitForStringValue()); + + executeJavaScript("testObject.setByteValue(undefined);"); + assertEquals(0, mTestObject.waitForByteValue()); + + executeJavaScript("testObject.setCharValue(undefined);"); + assertEquals('\u0000', mTestObject.waitForCharValue()); + + executeJavaScript("testObject.setShortValue(undefined);"); + assertEquals(0, mTestObject.waitForShortValue()); + + executeJavaScript("testObject.setIntValue(undefined);"); + assertEquals(0, mTestObject.waitForIntValue()); + + executeJavaScript("testObject.setLongValue(undefined);"); + assertEquals(0L, mTestObject.waitForLongValue()); + + executeJavaScript("testObject.setFloatValue(undefined);"); + assertEquals(0.0f, mTestObject.waitForFloatValue()); + + executeJavaScript("testObject.setDoubleValue(undefined);"); + assertEquals(0.0, mTestObject.waitForDoubleValue()); + + executeJavaScript("testObject.setBooleanValue(undefined);"); + assertFalse(mTestObject.waitForBooleanValue()); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java new file mode 100644 index 0000000..0ccd175 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. This test tests the + * use of fields. + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeFieldsTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeFieldsTest extends JavaBridgeTestBase { + private class TestObject extends Controller { + private String mStringValue; + + // These methods are used to control the test. + public synchronized void setStringValue(String x) { + mStringValue = x; + notifyResultIsReady(); + } + public synchronized String waitForStringValue() { + waitForResult(); + return mStringValue; + } + + public boolean booleanField = true; + public byte byteField = 42; + public char charField = '\u002A'; + public short shortField = 42; + public int intField = 42; + public long longField = 42L; + public float floatField = 42.0f; + public double doubleField = 42.0; + public String stringField = "foo"; + public Object objectField = new Object(); + public CustomType customTypeField = new CustomType(); + } + + // A custom type used when testing passing objects. + private class CustomType { + } + + TestObject mTestObject; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestObject = new TestObject(); + setUpWebView(mTestObject, "testObject"); + } + + // Note that this requires that we can pass a JavaScript string to Java. + protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { + executeJavaScript("testObject.setStringValue(" + script + ");"); + return mTestObject.waitForStringValue(); + } + + // The Java bridge does not provide access to fields. + // FIXME: Consider providing support for this. See See b/4408210. + public void testFieldTypes() throws Throwable { + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.booleanField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.byteField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.charField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.shortField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.intField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.longField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.floatField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.doubleField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.objectField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.stringField")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.customTypeField")); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java new file mode 100644 index 0000000..44d5cc6 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Part of the test suite for the WebView's Java Bridge. This test checks that + * we correctly convert Java values to JavaScript values when returning them + * from the methods of injected Java objects. + * + * The conversions should follow + * http://jdk6.java.net/plugin2/liveconnect/#JS_JAVA_CONVERSIONS. Places in + * which the implementation differs from the spec are marked with + * LIVECONNECT_COMPLIANCE. + * FIXME: Consider making our implementation more compliant, if it will not + * break backwards-compatibility. See b/4408210. + * + * To run this test ... + * adb shell am instrument -w -e class com.android.webviewtests.JavaBridgeReturnValuesTest \ + * com.android.webviewtests/android.test.InstrumentationTestRunner + */ + +package com.android.webviewtests; + +public class JavaBridgeReturnValuesTest extends JavaBridgeTestBase { + // An instance of this class is injected into the page to test returning + // Java values to JavaScript. + private class TestObject extends Controller { + private String mStringValue; + private boolean mBooleanValue; + + // These four methods are used to control the test. + public synchronized void setStringValue(String x) { + mStringValue = x; + notifyResultIsReady(); + } + public synchronized String waitForStringValue() { + waitForResult(); + return mStringValue; + } + public synchronized void setBooleanValue(boolean x) { + mBooleanValue = x; + notifyResultIsReady(); + } + public synchronized boolean waitForBooleanValue() { + waitForResult(); + return mBooleanValue; + } + + public boolean getBooleanValue() { + return true; + } + public byte getByteValue() { + return 42; + } + public char getCharValue() { + return '\u002A'; + } + public short getShortValue() { + return 42; + } + public int getIntValue() { + return 42; + } + public long getLongValue() { + return 42L; + } + public float getFloatValue() { + return 42.1f; + } + public float getFloatValueNoDecimal() { + return 42.0f; + } + public double getDoubleValue() { + return 42.1; + } + public double getDoubleValueNoDecimal() { + return 42.0; + } + public String getStringValue() { + return "foo"; + } + public String getEmptyStringValue() { + return ""; + } + public String getNullStringValue() { + return null; + } + public Object getObjectValue() { + return new Object(); + } + public Object getNullObjectValue() { + return null; + } + public CustomType getCustomTypeValue() { + return new CustomType(); + } + public void getVoidValue() { + } + } + + // A custom type used when testing passing objects. + private class CustomType { + } + + TestObject mTestObject; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mTestObject = new TestObject(); + setUpWebView(mTestObject, "testObject"); + } + + // Note that this requires that we can pass a JavaScript string to Java. + protected String executeJavaScriptAndGetStringResult(String script) throws Throwable { + executeJavaScript("testObject.setStringValue(" + script + ");"); + return mTestObject.waitForStringValue(); + } + + // Note that this requires that we can pass a JavaScript boolean to Java. + private boolean executeJavaScriptAndGetBooleanResult(String script) throws Throwable { + executeJavaScript("testObject.setBooleanValue(" + script + ");"); + return mTestObject.waitForBooleanValue(); + } + + public void testMethodReturnTypes() throws Throwable { + assertEquals("boolean", + executeJavaScriptAndGetStringResult("typeof testObject.getBooleanValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getByteValue()")); + // char values are returned to JavaScript as numbers. + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getCharValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getShortValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getIntValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getLongValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getFloatValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getFloatValueNoDecimal()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValue()")); + assertEquals("number", + executeJavaScriptAndGetStringResult("typeof testObject.getDoubleValueNoDecimal()")); + assertEquals("string", + executeJavaScriptAndGetStringResult("typeof testObject.getStringValue()")); + assertEquals("string", + executeJavaScriptAndGetStringResult("typeof testObject.getEmptyStringValue()")); + // LIVECONNECT_COMPLIANCE: This should have type object. + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.getNullStringValue()")); + assertEquals("object", + executeJavaScriptAndGetStringResult("typeof testObject.getObjectValue()")); + assertEquals("object", + executeJavaScriptAndGetStringResult("typeof testObject.getNullObjectValue()")); + assertEquals("object", + executeJavaScriptAndGetStringResult("typeof testObject.getCustomTypeValue()")); + assertEquals("undefined", + executeJavaScriptAndGetStringResult("typeof testObject.getVoidValue()")); + } + + public void testMethodReturnValues() throws Throwable { + // We do the string comparison in JavaScript, to avoid relying on the + // coercion algorithm from JavaScript to Java. + assertTrue(executeJavaScriptAndGetBooleanResult("testObject.getBooleanValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getByteValue()")); + // char values are returned to JavaScript as numbers. + assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getCharValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getShortValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getIntValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult("42 === testObject.getLongValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult( + "Math.abs(42.1 - testObject.getFloatValue()) < 0.001")); + assertTrue(executeJavaScriptAndGetBooleanResult( + "42.0 === testObject.getFloatValueNoDecimal()")); + assertTrue(executeJavaScriptAndGetBooleanResult( + "Math.abs(42.1 - testObject.getDoubleValue()) < 0.001")); + assertTrue(executeJavaScriptAndGetBooleanResult( + "42.0 === testObject.getDoubleValueNoDecimal()")); + assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.getStringValue()")); + assertEquals("", executeJavaScriptAndGetStringResult("testObject.getEmptyStringValue()")); + assertTrue(executeJavaScriptAndGetBooleanResult("undefined === testObject.getVoidValue()")); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java new file mode 100644 index 0000000..1af3f63 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common functionality for testing the WebView's Java Bridge. + */ + +package com.android.webviewtests; + +import android.test.ActivityInstrumentationTestCase2; +import android.util.Log; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import junit.framework.Assert; + +public class JavaBridgeTestBase extends ActivityInstrumentationTestCase2<WebViewStubActivity> { + protected class TestWebViewClient extends WebViewClient { + private boolean mIsPageFinished; + @Override + public synchronized void onPageFinished(WebView webView, String url) { + mIsPageFinished = true; + notify(); + } + public synchronized void waitForOnPageFinished() throws RuntimeException { + while (!mIsPageFinished) { + try { + wait(5000); + } catch (Exception e) { + continue; + } + if (!mIsPageFinished) { + throw new RuntimeException("Timed out waiting for onPageFinished()"); + } + } + mIsPageFinished = false; + } + } + + protected class Controller { + private boolean mIsResultReady; + + protected synchronized void notifyResultIsReady() { + mIsResultReady = true; + notify(); + } + protected synchronized void waitForResult() { + while (!mIsResultReady) { + try { + wait(5000); + } catch (Exception e) { + continue; + } + if (!mIsResultReady) { + Assert.fail("Wait timed out"); + } + } + mIsResultReady = false; + } + } + + protected TestWebViewClient mWebViewClient; + + public JavaBridgeTestBase() { + super(WebViewStubActivity.class); + } + + // Sets up the WebView and injects the supplied object. Intended to be called from setUp(). + protected void setUpWebView(final Object object, final String name) throws Exception { + mWebViewClient = new TestWebViewClient(); + // This starts the activity, so must be called on the test thread. + final WebViewStubActivity activity = getActivity(); + // On the UI thread, load an empty page and wait for it to finish + // loading so that the Java object is injected. + try { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + WebView webView = activity.getWebView(); + webView.addJavascriptInterface(object, name); + webView.getSettings().setJavaScriptEnabled(true); + webView.setWebViewClient(mWebViewClient); + webView.loadData("<!DOCTYPE html><title></title>", "text/html", null); + } + }); + mWebViewClient.waitForOnPageFinished(); + } catch (Throwable e) { + throw new RuntimeException("Failed to set up WebView: " + Log.getStackTraceString(e)); + } + } + + protected void executeJavaScript(final String script) throws Throwable { + runTestOnUiThread(new Runnable() { + @Override + public void run() { + getWebView().loadUrl("javascript:" + script); + } + }); + } + + protected WebView getWebView() { + return getActivity().getWebView(); + } +} diff --git a/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java b/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java new file mode 100644 index 0000000..ccfd3d5 --- /dev/null +++ b/tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.webviewtests; + +import com.android.webviewtests.R; + +import android.app.Activity; +import android.os.Bundle; +import android.webkit.WebView; + +public class WebViewStubActivity extends Activity { + private WebView mWebView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.webview_layout); + mWebView = (WebView) findViewById(R.id.web_page); + } + + public WebView getWebView() { + return mWebView; + } +} diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk index 31e2ec5..88794c2 100644 --- a/tests/backup/Android.mk +++ b/tests/backup/Android.mk @@ -24,7 +24,7 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE_TAGS := optional LOCAL_MODULE := backup_helper_test LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) -LOCAL_SHARED_LIBRARIES := libutils +LOCAL_SHARED_LIBRARIES := libandroidfw libutils include $(BUILD_EXECUTABLE) diff --git a/tests/backup/backup_helper_test.cpp b/tests/backup/backup_helper_test.cpp index 04358ad..b5f6ff5 100644 --- a/tests/backup/backup_helper_test.cpp +++ b/tests/backup/backup_helper_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <utils/BackupHelpers.h> +#include <androidfw/BackupHelpers.h> #include <stdio.h> #include <string.h> diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java index 4cacbc4..cceed16 100644 --- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java @@ -39,7 +39,7 @@ public class ActivityManagerPermissionTests extends TestCase { @SmallTest public void testREORDER_TASKS() { try { - mAm.moveTaskToFront(0, 0); + mAm.moveTaskToFront(0, 0, null); fail("IActivityManager.moveTaskToFront did not throw SecurityException as" + " expected"); } catch (SecurityException e) { diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index c3ac22c..1f6279c 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -255,41 +255,6 @@ public class WindowManagerPermissionTests extends TestCase { } @SmallTest - public void testINJECT_EVENTS() { - try { - mWm.injectKeyEvent(new KeyEvent(0, 0), false); - fail("IWindowManager.injectKeyEvent did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.injectPointerEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0), false); - fail("IWindowManager.injectPointerEvent did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.injectTrackballEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0), false); - fail("IWindowManager.injectTrackballEvent did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - } - - @SmallTest public void testDISABLE_KEYGUARD() { Binder token = new Binder(); try { @@ -347,73 +312,9 @@ public class WindowManagerPermissionTests extends TestCase { } @SmallTest - public void testREAD_INPUT_STATE() { - try { - mWm.getSwitchState(0); - fail("IWindowManager.getSwitchState did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.getSwitchStateForDevice(0, 0); - fail("IWindowManager.getSwitchStateForDevice did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.getScancodeState(0); - fail("IWindowManager.getScancodeState did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.getScancodeStateForDevice(0, 0); - fail("IWindowManager.getScancodeStateForDevice did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.getKeycodeState(0); - fail("IWindowManager.getKeycodeState did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - - try { - mWm.getKeycodeStateForDevice(0, 0); - fail("IWindowManager.getKeycodeStateForDevice did not throw SecurityException as" - + " expected"); - } catch (SecurityException e) { - // expected - } catch (RemoteException e) { - fail("Unexpected remote exception"); - } - } - - @SmallTest public void testSET_ORIENTATION() { try { - mWm.updateRotation(true); - mWm.getSwitchState(0); + mWm.updateRotation(true, false); fail("IWindowManager.updateRotation did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -424,7 +325,6 @@ public class WindowManagerPermissionTests extends TestCase { try { mWm.freezeRotation(-1); - mWm.getSwitchState(0); fail("IWindowManager.freezeRotation did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -435,7 +335,6 @@ public class WindowManagerPermissionTests extends TestCase { try { mWm.thawRotation(); - mWm.getSwitchState(0); fail("IWindowManager.thawRotation did not throw SecurityException as" + " expected"); } catch (SecurityException e) { diff --git a/tests/touchlag/Android.mk b/tests/touchlag/Android.mk new file mode 100644 index 0000000..4f8aa1e --- /dev/null +++ b/tests/touchlag/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + touchlag.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils libutils \ + +LOCAL_MODULE:= test-touchlag + +LOCAL_MODULE_TAGS := tests + +include $(BUILD_EXECUTABLE) diff --git a/tests/touchlag/touchlag.cpp b/tests/touchlag/touchlag.cpp new file mode 100644 index 0000000..df4befb --- /dev/null +++ b/tests/touchlag/touchlag.cpp @@ -0,0 +1,294 @@ +/* + * 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 <stdint.h> +#include <sys/types.h> + +#include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/fb.h> +#include <linux/input.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <cutils/memory.h> +#include <asm-generic/mman.h> +#include <sys/mman.h> +#include <utils/threads.h> +#include <unistd.h> +#include <math.h> + +using namespace android; + +#ifndef FBIO_WAITFORVSYNC +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#endif + +struct Buffer { + size_t w; + size_t h; + size_t s; + union { + void* addr; + uint32_t* pixels; + }; +}; + +void clearBuffer(Buffer* buf, uint32_t pixel) { + android_memset32(buf->pixels, pixel, buf->s * buf->h * 4); +} + +void drawTwoPixels(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) { + if (y>0 && y<ssize_t(buf->h)) { + uint32_t* bits = buf->pixels + y * buf->s; + if (x>=0 && x<buf->w) { + bits[x] = pixel; + } + ssize_t W(w); + if ((x+W)>=0 && (x+W)<buf->w) { + bits[x+W] = pixel; + } + } +} + +void drawHLine(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w) { + if (y>0 && y<ssize_t(buf->h)) { + ssize_t W(w); + if (x<0) { + W += x; + x = 0; + } + if (x+w > buf->w) { + W = buf->w - x; + } + if (W>0) { + uint32_t* bits = buf->pixels + y * buf->s + x; + android_memset32(bits, pixel, W*4); + } + } +} + +void drawRect(Buffer* buf, uint32_t pixel, ssize_t x, ssize_t y, size_t w, size_t h) { + ssize_t W(w), H(h); + if (x<0) { + w += x; + x = 0; + } + if (y<0) { + h += y; + y = 0; + } + if (x+w > buf->w) W = buf->w - x; + if (y+h > buf->h) H = buf->h - y; + if (W>0 && H>0) { + uint32_t* bits = buf->pixels + y * buf->s + x; + for (ssize_t i=0 ; i<H ; i++) { + android_memset32(bits, pixel, W*4); + bits += buf->s; + } + } +} + +void drawCircle(Buffer* buf, uint32_t pixel, + size_t x0, size_t y0, size_t radius, bool filled = false) { + ssize_t f = 1 - radius; + ssize_t ddF_x = 1; + ssize_t ddF_y = -2 * radius; + ssize_t x = 0; + ssize_t y = radius; + if (filled) { + drawHLine(buf, pixel, x0-radius, y0, 2*radius); + } else { + drawTwoPixels(buf, pixel, x0-radius, y0, 2*radius); + } + while (x < y) { + if (f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + if (filled) { + drawHLine(buf, pixel, x0-x, y0+y, 2*x); + drawHLine(buf, pixel, x0-x, y0-y, 2*x); + drawHLine(buf, pixel, x0-y, y0+x, 2*y); + drawHLine(buf, pixel, x0-y, y0-x, 2*y); + } else { + drawTwoPixels(buf, pixel, x0-x, y0+y, 2*x); + drawTwoPixels(buf, pixel, x0-x, y0-y, 2*x); + drawTwoPixels(buf, pixel, x0-y, y0+x, 2*y); + drawTwoPixels(buf, pixel, x0-y, y0-x, 2*y); + } + } +} + +class TouchEvents { + class EventThread : public Thread { + int fd; + + virtual bool threadLoop() { + input_event event; + int first_down = 0; + do { + read(fd, &event, sizeof(event)); + if (event.type == EV_ABS) { + if (event.code == ABS_MT_TRACKING_ID) { + down = event.value == -1 ? 0 : 1; + first_down = down; + } + if (event.code == ABS_MT_POSITION_X) { + x = event.value; + } + if (event.code == ABS_MT_POSITION_Y) { + y = event.value; + } + } + } while (event.type == EV_SYN); + return true; + } + + public: + int x, y, down; + EventThread() : Thread(false), + x(0), y(0), down(0) + { + fd = open("/dev/input/event1", O_RDONLY); + } +}; + sp<EventThread> thread; + +public: + TouchEvents() { + thread = new EventThread(); + thread->run("EventThread", PRIORITY_URGENT_DISPLAY); + } + + int getMostRecentPosition(int* x, int* y) { + *x = thread->x; + *y = thread->y; + return thread->down; + } +}; + + +struct Queue { + struct position { + int x, y; + }; + int index; + position q[16]; + Queue() : index(0) { } + void push(int x, int y) { + index++; + index &= 0xF; + q[index].x = x; + q[index].y = y; + } + void get(int lag, int* x, int* y) { + const int i = (index - lag) & 0xF; + *x = q[i].x; + *y = q[i].y; + } +}; + +extern char *optarg; +extern int optind; +extern int optopt; +extern int opterr; +extern int optreset; + +void usage(const char* name) { + printf("\nusage: %s [-h] [-l lag]\n", name); +} + +int main(int argc, char** argv) { + fb_var_screeninfo vi; + fb_fix_screeninfo fi; + + int lag = 0; + int fd = open("/dev/graphics/fb0", O_RDWR); + ioctl(fd, FBIOGET_VSCREENINFO, &vi); + ioctl(fd, FBIOGET_FSCREENINFO, &fi); + void* bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + Buffer framebuffer; + framebuffer.w = vi.xres; + framebuffer.h = vi.yres; + framebuffer.s = fi.line_length / (vi.bits_per_pixel >> 3); + framebuffer.addr = bits; + + int ch; + while ((ch = getopt(argc, argv, "hl:")) != -1) { + switch (ch) { + case 'l': + lag = atoi(optarg); + break; + case 'h': + default: + usage(argv[0]); + exit(0); + } + } + argc -= optind; + argv += optind; + + + TouchEvents touch; + Queue queue; + + + int x=0, y=0, down=0; + int lag_x=0, lag_y=0; + + clearBuffer(&framebuffer, 0); + while (true) { + uint32_t crt = 0; + int err = ioctl(fd, FBIO_WAITFORVSYNC, &crt); + + // draw beam marker + drawRect(&framebuffer, 0x400000, framebuffer.w-2, 0, 2, framebuffer.h); + // erase screen + if (lag) { + drawCircle(&framebuffer, 0, lag_x, lag_y, 100); + drawHLine(&framebuffer, 0, 0, lag_y, 32); + } + drawCircle(&framebuffer, 0, x, y, 100, true); + drawHLine(&framebuffer, 0, 0, y, 32); + + // draw a line at y=1000 + drawHLine(&framebuffer, 0x808080, 0, 1000, framebuffer.w); + + // get touch events + touch.getMostRecentPosition(&x, &y); + queue.push(x, y); + queue.get(lag, &lag_x, &lag_y); + + if (lag) { + drawCircle(&framebuffer, 0x00FF00, lag_x, lag_y, 100); + drawHLine(&framebuffer, 0x00FF00, 0, lag_y, 32); + } + + drawCircle(&framebuffer, 0xFFFFFF, x, y, 100, true); + drawHLine(&framebuffer, 0xFFFFFF, 0, y, 32); + + // draw end of frame beam marker + drawRect(&framebuffer, 0x004000, framebuffer.w-2, 0, 2, framebuffer.h); + } + + close(fd); + return 0; +} |