summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ActivityTests/res/anim/slow_enter.xml30
-rw-r--r--tests/ActivityTests/res/anim/slow_exit.xml30
-rw-r--r--tests/ActivityTests/res/interpolator/slow_enter.xml22
-rw-r--r--tests/ActivityTests/res/values/themes.xml25
-rw-r--r--tests/ActivityTests/src/com/google/android/test/activity/ActivityTestMain.java17
-rw-r--r--tests/BiDiTests/Android.mk (renamed from tests/BiDiTests/Android-private.mk)0
-rw-r--r--tests/BiDiTests/AndroidManifest.xml4
-rw-r--r--tests/BiDiTests/res/layout/basic.xml6
-rw-r--r--tests/BiDiTests/res/layout/grid_layout_code.xml (renamed from tests/TileBenchmark/tests/AndroidManifest.xml)17
-rw-r--r--tests/BiDiTests/res/layout/grid_layout_locale.xml74
-rw-r--r--tests/BiDiTests/res/layout/grid_layout_ltr.xml95
-rw-r--r--tests/BiDiTests/res/layout/grid_layout_rtl.xml95
-rw-r--r--tests/BiDiTests/res/layout/textview_alignment_ltr.xml578
-rw-r--r--tests/BiDiTests/res/layout/textview_alignment_rtl.xml578
-rw-r--r--tests/BiDiTests/res/values/strings.xml11
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java24
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java122
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java122
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLocale.java32
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutLtr.java32
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutRtl.java32
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentLtr.java31
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestTextViewAlignmentRtl.java31
-rw-r--r--tests/BiDiTests/src/com/android/bidi/BiDiTestView.java6
-rw-r--r--tests/CoreTests/android/core/CharArrayWriterTest.java48
-rw-r--r--tests/CoreTests/android/core/ClassLoaderTest.java243
-rw-r--r--tests/CoreTests/android/core/ClassTest.java337
-rw-r--r--tests/CoreTests/android/core/MiscRegressionTest.java452
-rw-r--r--tests/CoreTests/android/core/RegexTest.java287
-rw-r--r--tests/DataIdleTest/src/com/android/tests/dataidle/DataIdleTest.java15
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java2
-rwxr-xr-xtests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java24
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java4
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java32
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java196
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java92
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/TestShellCallback.java1
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/forwarder/ForwardService.java14
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsExecutor.java24
-rw-r--r--tests/DumpRenderTree2/src/com/android/dumprendertree2/TextResult.java3
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml85
-rw-r--r--tests/HwAccelerationTest/res/layout/date_picker.xml83
-rw-r--r--tests/HwAccelerationTest/res/layout/transforms_and_animations.xml145
-rw-r--r--tests/HwAccelerationTest/res/layout/view_properties.xml81
-rw-r--r--tests/HwAccelerationTest/res/values/strings.xml19
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java57
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/DatePicker.java474
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/DatePickerActivity.java38
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/MatrixActivity.java56
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/PaintDrawFilterActivity.java64
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java116
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/PosTextActivity.java79
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/TextActivity.java9
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/TextOnPathActivity.java153
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/TransformsAndAnimationsActivity.java201
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/ViewPropertyAlphaActivity.java145
-rw-r--r--tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/ComputePerf.java26
-rw-r--r--tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/LaunchTest.java15
-rw-r--r--tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs5
-rw-r--r--tests/RenderScriptTests/Fountain_v11/Android.mk32
-rw-r--r--tests/RenderScriptTests/Fountain_v11/AndroidManifest.xml15
-rw-r--r--tests/RenderScriptTests/Fountain_v11/_index.html5
-rw-r--r--tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.pngbin0 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainRS.java72
-rw-r--r--tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/FountainView.java106
-rw-r--r--tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/Fountain_v11.java96
-rw-r--r--tests/RenderScriptTests/Fountain_v11/src/com/android/fountain/fountain.rs69
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java3
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs1
-rw-r--r--tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/vertical_blur.rs1
-rw-r--r--tests/RenderScriptTests/ModelViewer/src/com/android/modelviewer/simplemodel.rs12
-rw-r--r--tests/RenderScriptTests/PerfTest/res/menu/loader_menu.xml7
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/singletexf.glsl8
-rw-r--r--tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl8
-rw-r--r--tests/RenderScriptTests/PerfTest/res/values/strings.xml4
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java171
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/MeshTest.java170
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java27
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchBaseTest.java26
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java568
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java26
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/TextTest.java93
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/TorusTest.java272
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/UiTest.java337
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs158
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/mesh_test.rs89
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs763
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/subtest_def.rsh4
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/text_test.rs10
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/torus_test.rs20
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/ui_test.rs444
-rw-r--r--tests/RenderScriptTests/SampleTest/Android.mk26
-rw-r--r--tests/RenderScriptTests/SampleTest/AndroidManifest.xml34
-rw-r--r--tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.pngbin0 -> 23004 bytes
-rw-r--r--tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.pngbin0 -> 2796 bytes
-rw-r--r--tests/RenderScriptTests/SampleTest/res/layout/rs.xml84
-rw-r--r--tests/RenderScriptTests/SampleTest/res/values/strings.xml28
-rw-r--r--tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/SampleRSActivity.java169
-rw-r--r--tests/RenderScriptTests/SampleTest/src/com/android/rs/sample/sample.rs43
-rw-r--r--tests/RenderScriptTests/SceneGraph/Android.mk26
-rw-r--r--tests/RenderScriptTests/SceneGraph/AndroidManifest.xml29
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/blue.jpgbin0 -> 12773 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpgbin0 -> 17021 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/green.jpgbin0 -> 12368 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/grey.jpgbin0 -> 10744 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/orange.jpgbin0 -> 11574 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3dbin0 -> 346140 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae1102
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/paint.jpgbin0 -> 11350 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/assets/red.jpgbin0 -> 11975 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.pngbin0 -> 7529 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.pngbin0 -> 292580 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml25
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl15
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl17
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl7
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl19
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/diffuse_lights.glsl22
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl23
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl26
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl22
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl29
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/robot.a3dbin0 -> 144528 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl13
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl22
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl7
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3dbin0 -> 29068 bytes
-rw-r--r--tests/RenderScriptTests/SceneGraph/res/values/strings.xml24
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java118
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java563
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java139
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java215
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java146
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java174
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java111
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java60
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java43
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java124
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java111
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java224
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java39
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java47
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java373
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java61
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java503
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java76
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java162
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java113
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java57
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java114
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java67
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java69
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java98
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java85
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java113
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs66
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs86
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs61
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs30
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs33
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs36
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh193
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs244
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh323
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs127
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs29
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java110
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java192
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleApp.java46
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppRS.java207
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/SimpleAppView.java62
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java115
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java113
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java270
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java153
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java109
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs86
-rw-r--r--tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh52
-rw-r--r--tests/RenderScriptTests/ShadersTest/src/com/android/shaderstest/shaderstest.rs12
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/Android.mk29
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/AndroidManifest.xml21
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/res/drawable/test_pattern.pngbin0 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/CameraCapture.java234
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaque.java71
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueRS.java83
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/SurfaceTextureOpaqueView.java60
-rw-r--r--tests/RenderScriptTests/SurfaceTexture/src/com/example/android/rs/sto/sto.rs58
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java16
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_array_init.java95
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_atomic.java40
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_constant.java57
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_convert.java40
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java132
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach.java5
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java75
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_noroot.java57
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_primitives.java3
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java81
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java175
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_rstime.java1
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java150
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_struct.java55
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UT_vector.java2
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java22
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/array_init.rs58
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/atomic.rs77
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/constant.rs19
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/convert.rs37
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs158
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/foreach.rs42
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs64
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/noroot.rs44
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs37
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs128
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/rstime.rs2
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs63
-rw-r--r--tests/RenderScriptTests/tests/src/com/android/rs/test/struct.rs37
-rw-r--r--tests/RenderScriptTests/tests_v11/Android.mk31
-rw-r--r--tests/RenderScriptTests/tests_v11/AndroidManifest.xml16
-rw-r--r--tests/RenderScriptTests/tests_v11/res/drawable/test_pattern.pngbin0 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestCore.java206
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTestView.java97
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/RSTest_v11.java84
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_fp_mad.java40
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_math.java40
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_primitives.java104
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rsdebug.java40
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstime.java40
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UT_rstypes.java40
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/UnitTest.java106
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/fp_mad.rs174
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/math.rs348
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/primitives.rs61
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rsdebug.rs56
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rslist.rs107
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstime.rs52
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/rstypes.rs79
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/shared.rsh38
-rw-r--r--tests/RenderScriptTests/tests_v11/src/com/android/rs/test/test_root.rs23
-rw-r--r--tests/RenderScriptTests/tests_v14/Android.mk27
-rw-r--r--tests/RenderScriptTests/tests_v14/AndroidManifest.xml16
-rw-r--r--tests/RenderScriptTests/tests_v14/res/drawable-nodpi/test_pattern.pngbin0 -> 307 bytes
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestCore.java210
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTestView.java97
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/RSTest_v14.java91
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_alloc.java67
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_foreach.java56
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_fp_mad.java40
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_math.java40
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_primitives.java104
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_refcount.java50
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rsdebug.java40
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstime.java40
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_rstypes.java40
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UT_vector.java318
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/UnitTest.java117
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/alloc.rs94
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/foreach.rs42
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/fp_mad.rs174
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs462
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.bak423
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/math.rs.orig436
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/primitives.rs61
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/refcount.rs13
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rsdebug.rs56
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rslist.rs107
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstime.rs52
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/rstypes.rs79
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/shared.rsh38
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/test_root.rs23
-rw-r--r--tests/RenderScriptTests/tests_v14/src/com/android/rs/test/vector.rs198
-rw-r--r--tests/SerialChat/Android.mk26
-rw-r--r--tests/SerialChat/AndroidManifest.xml31
-rw-r--r--tests/SerialChat/res/layout/serial_chat.xml47
-rw-r--r--tests/SerialChat/src/com/android/serialchat/SerialChat.java163
-rw-r--r--tests/SmokeTest/tests/AndroidManifest.xml22
-rw-r--r--tests/SmokeTest/tests/src/com/android/smoketest/ProcessErrorsTest.java256
-rw-r--r--tests/SmokeTest/tests/src/com/android/smoketest/SmokeTestRunner.java94
-rw-r--r--tests/SmokeTestApps/Android.mk12
-rw-r--r--tests/SmokeTestApps/AndroidManifest.xml45
-rw-r--r--tests/SmokeTestApps/README3
-rw-r--r--tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp.java37
-rw-r--r--tests/SmokeTestApps/src/com/android/smoketest/triggers/CrashyApp2.java38
-rw-r--r--tests/SmokeTestApps/src/com/android/smoketest/triggers/UnresponsiveApp.java44
-rw-r--r--tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java58
-rw-r--r--tests/TileBenchmark/Android.mk10
-rw-r--r--tests/TileBenchmark/AndroidManifest.xml4
-rw-r--r--tests/TileBenchmark/res/layout/main.xml80
-rw-r--r--tests/TileBenchmark/res/values/strings.xml16
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PerformanceTest.java304
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java115
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java68
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/ProfiledWebView.java153
-rw-r--r--tests/TileBenchmark/src/com/test/tilebenchmark/RunData.java3
-rw-r--r--tests/TileBenchmark/tests/Android.mk16
-rw-r--r--tests/TileBenchmark/tests/src/com/test/tilebenchmark/PerformanceTest.java167
-rw-r--r--tests/TtsTests/Android.mk28
-rw-r--r--tests/TtsTests/AndroidManifest.xml43
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java58
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java78
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java229
-rw-r--r--tests/WebViewTests/Android.mk27
-rw-r--r--tests/WebViewTests/AndroidManifest.xml32
-rw-r--r--tests/WebViewTests/res/layout/webview_layout.xml25
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayCoercionTest.java625
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeArrayTest.java226
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeBasicsTest.java396
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeCoercionTest.java646
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeFieldsTest.java100
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeReturnValuesTest.java199
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/JavaBridgeTestBase.java117
-rw-r--r--tests/WebViewTests/src/com/android/webviewtests/WebViewStubActivity.java38
-rw-r--r--tests/backup/Android.mk2
-rw-r--r--tests/backup/backup_helper_test.cpp2
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java2
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java103
-rw-r--r--tests/touchlag/Android.mk14
-rw-r--r--tests/touchlag/touchlag.cpp294
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
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/tests/RenderScriptTests/Fountain_v11/res/drawable/test_pattern.png
Binary files differ
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
new file mode 100644
index 0000000..27c4618
--- /dev/null
+++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/city.png
Binary files differ
diff --git a/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png
new file mode 100644
index 0000000..98cf963
--- /dev/null
+++ b/tests/RenderScriptTests/SampleTest/res/drawable-nodpi/twobytwo.png
Binary files differ
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
new file mode 100644
index 0000000..494e77a
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg
new file mode 100644
index 0000000..2fcecb0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/green.jpg b/tests/RenderScriptTests/SceneGraph/assets/green.jpg
new file mode 100644
index 0000000..a86a754
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/green.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/grey.jpg b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg
new file mode 100644
index 0000000..5870b1a
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/orange.jpg b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg
new file mode 100644
index 0000000..7dbe942
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d
new file mode 100644
index 0000000..07318ae
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d
Binary files differ
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
new file mode 100644
index 0000000..0791045
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/red.jpg b/tests/RenderScriptTests/SceneGraph/assets/red.jpg
new file mode 100644
index 0000000..320a2a6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/red.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png
new file mode 100644
index 0000000..ff34a7f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/icon.png
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
Binary files differ
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
new file mode 100644
index 0000000..f48895c
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d
Binary files differ
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
new file mode 100644
index 0000000..56eff04
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/unit_obj.a3d
Binary files differ
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, &currentCam->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, &currentCam->view);
+ break;
+ case SHADER_PARAM_TRANSFORM_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->proj);
+ break;
+ case SHADER_PARAM_TRANSFORM_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->viewProj);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->view);
+ rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr,
+ (rs_matrix4x4*)dataPtr,
+ &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->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
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/tests/RenderScriptTests/SurfaceTexture/res/drawable/test_pattern.png
Binary files differ
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
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/tests/RenderScriptTests/tests_v11/res/drawable/test_pattern.png
Binary files differ
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
new file mode 100644
index 0000000..e7d1455
--- /dev/null
+++ b/tests/RenderScriptTests/tests_v14/res/drawable-nodpi/test_pattern.png
Binary files differ
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;
+}