summaryrefslogtreecommitdiffstats
path: root/tests/RenderScriptTests/PerfTest/src/com
diff options
context:
space:
mode:
authorAlex Sakhartchouk <alexst@google.com>2011-02-22 10:30:32 -0800
committerAlex Sakhartchouk <alexst@google.com>2011-02-22 10:30:32 -0800
commitc29a4442812d5f0e9f1af13b36cb6a806b6b46e0 (patch)
tree65a6b04a509557293f56d6c14d99daffafc568dd /tests/RenderScriptTests/PerfTest/src/com
parentbdbdf0148d8ad36f8425b9be81c03dbe81333354 (diff)
downloadframeworks_base-c29a4442812d5f0e9f1af13b36cb6a806b6b46e0.zip
frameworks_base-c29a4442812d5f0e9f1af13b36cb6a806b6b46e0.tar.gz
frameworks_base-c29a4442812d5f0e9f1af13b36cb6a806b6b46e0.tar.bz2
Moving renderscript tests away from the library to a dedicated test folder.
Change-Id: I7d8e20a17513f167eae3681d77463c01f4fa24a7
Diffstat (limited to 'tests/RenderScriptTests/PerfTest/src/com')
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java71
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java407
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java91
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs786
-rw-r--r--tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh83
5 files changed, 1438 insertions, 0 deletions
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
new file mode 100644
index 0000000..cfe1970
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBench.java
@@ -0,0 +1,71 @@
+/*
+ * 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.perftest;
+
+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 RsBench extends Activity {
+
+ private RsBenchView 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 RsBenchView(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();
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
new file mode 100644
index 0000000..9757ec6
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchRS.java
@@ -0,0 +1,407 @@
+/*
+ * 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.perftest;
+
+import java.io.Writer;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.*;
+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.Sampler.Value;
+import android.util.Log;
+
+
+public class RsBenchRS {
+
+ int mWidth;
+ int mHeight;
+
+ public RsBenchRS() {
+ }
+
+ public void init(RenderScriptGL rs, Resources res, int width, int height) {
+ mRS = rs;
+ mRes = res;
+ mWidth = width;
+ mHeight = height;
+ mOptionsARGB.inScaled = false;
+ mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ mMode = 0;
+ mMaxModes = 0;
+ initRS();
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+
+ private Sampler mLinearClamp;
+ private Sampler mLinearWrap;
+ private Sampler mMipLinearWrap;
+ private Sampler mNearestClamp;
+ private Sampler mMipLinearAniso8;
+ private Sampler mMipLinearAniso15;
+
+ private ProgramStore mProgStoreBlendNoneDepth;
+ private ProgramStore mProgStoreBlendNone;
+ private ProgramStore mProgStoreBlendAlpha;
+ private ProgramStore mProgStoreBlendAdd;
+
+ private ProgramFragment mProgFragmentTexture;
+ private ProgramFragment mProgFragmentColor;
+
+ private ProgramVertex mProgVertex;
+ private ProgramVertexFixedFunction.Constants mPVA;
+
+ // 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 ProgramRaster mCullBack;
+ private ProgramRaster mCullFront;
+ private ProgramRaster mCullNone;
+
+ private Allocation mTexTorus;
+ private Allocation mTexOpaque;
+ private Allocation mTexTransparent;
+ private Allocation mTexChecker;
+
+ private Mesh m10by10Mesh;
+ private Mesh m100by100Mesh;
+ private Mesh mWbyHMesh;
+ private Mesh mTorus;
+
+ Font mFontSans;
+ Font mFontSerif;
+ Font mFontSerifBold;
+ Font mFontSerifItalic;
+ Font mFontSerifBoldItalic;
+ Font mFontMono;
+ private Allocation mTextAlloc;
+
+ private ScriptC_rsbench mScript;
+
+ private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
+
+ int mMode;
+ int mMaxModes;
+
+ public void onActionDown(int x, int y) {
+ mMode ++;
+ mMode = mMode % mMaxModes;
+ mScript.set_gDisplayMode(mMode);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ private void initProgramFragment() {
+
+ ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+ texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+ ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+ mProgFragmentTexture = texBuilder.create();
+ mProgFragmentTexture.bindSampler(mLinearClamp, 0);
+
+ ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
+ colBuilder.setVaryingColor(false);
+ mProgFragmentColor = colBuilder.create();
+
+ mScript.set_gProgFragmentColor(mProgFragmentColor);
+ mScript.set_gProgFragmentTexture(mProgFragmentTexture);
+ }
+
+ private void initProgramVertex() {
+ ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+ mProgVertex = pvb.create();
+
+ mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+ ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
+ Matrix4f proj = new Matrix4f();
+ proj.loadOrthoWindow(mWidth, mHeight);
+ mPVA.setProjection(proj);
+
+ mScript.set_gProgVertex(mProgVertex);
+ }
+
+ private void initCustomShaders() {
+ mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
+ mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
+ mScript.bind_gVSConstants(mVSConst);
+ mScript.bind_gFSConstants(mFSConst);
+
+ mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1);
+ mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1);
+ mScript.bind_gVSConstPixel(mVSConstPixel);
+ mScript.bind_gFSConstPixel(mFSConstPixel);
+
+ // 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_gProgVertexCustom(mProgVertexCustom);
+ mScript.set_gProgFragmentCustom(mProgFragmentCustom);
+ mScript.set_gProgVertexPixelLight(mProgVertexPixelLight);
+ mScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove);
+ mScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight);
+ 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);
+
+ mScript.set_gTexTorus(mTexTorus);
+ mScript.set_gTexOpaque(mTexOpaque);
+ mScript.set_gTexTransparent(mTexTransparent);
+ mScript.set_gTexChecker(mTexChecker);
+ }
+
+ 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
+ mFontSerifBold = Font.create(mRS, mRes, "serif", Font.Style.BOLD, 8);
+ mFontSerifItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+ mFontSerifBoldItalic = Font.create(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
+ mFontMono = Font.create(mRS, mRes, "mono", Font.Style.NORMAL, 8);
+
+ mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
+
+ mScript.set_gFontSans(mFontSans);
+ mScript.set_gFontSerif(mFontSerif);
+ mScript.set_gFontSerifBold(mFontSerifBold);
+ mScript.set_gFontSerifItalic(mFontSerifItalic);
+ mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
+ mScript.set_gFontMono(mFontMono);
+ mScript.set_gTextAlloc(mTextAlloc);
+ }
+
+ private void initMesh() {
+ m10by10Mesh = getMbyNMesh(mWidth, mHeight, 10, 10);
+ mScript.set_g10by10Mesh(m10by10Mesh);
+ m100by100Mesh = getMbyNMesh(mWidth, mHeight, 100, 100);
+ mScript.set_g100by100Mesh(m100by100Mesh);
+ mWbyHMesh= getMbyNMesh(mWidth, mHeight, mWidth/4, mHeight/4);
+ mScript.set_gWbyHMesh(mWbyHMesh);
+
+ 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();
+ mScript.set_gTorusMesh(mTorus);
+ }
+ }
+
+ private void initSamplers() {
+ Sampler.Builder bs = new Sampler.Builder(mRS);
+ bs.setMinification(Sampler.Value.LINEAR);
+ bs.setMagnification(Sampler.Value.LINEAR);
+ bs.setWrapS(Sampler.Value.WRAP);
+ bs.setWrapT(Sampler.Value.WRAP);
+ mLinearWrap = bs.create();
+
+ mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
+ mNearestClamp = Sampler.CLAMP_NEAREST(mRS);
+ mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS);
+
+ bs = new Sampler.Builder(mRS);
+ bs.setMinification(Sampler.Value.LINEAR_MIP_LINEAR);
+ bs.setMagnification(Sampler.Value.LINEAR);
+ bs.setWrapS(Sampler.Value.WRAP);
+ bs.setWrapT(Sampler.Value.WRAP);
+ bs.setAnisotropy(8.0f);
+ mMipLinearAniso8 = bs.create();
+ bs.setAnisotropy(15.0f);
+ mMipLinearAniso15 = bs.create();
+
+ mScript.set_gLinearClamp(mLinearClamp);
+ mScript.set_gLinearWrap(mLinearWrap);
+ mScript.set_gMipLinearWrap(mMipLinearWrap);
+ mScript.set_gMipLinearAniso8(mMipLinearAniso8);
+ mScript.set_gMipLinearAniso15(mMipLinearAniso15);
+ mScript.set_gNearestClamp(mNearestClamp);
+ }
+
+ private void initProgramRaster() {
+ mCullBack = ProgramRaster.CULL_BACK(mRS);
+ mCullFront = ProgramRaster.CULL_FRONT(mRS);
+ mCullNone = ProgramRaster.CULL_NONE(mRS);
+
+ mScript.set_gCullBack(mCullBack);
+ mScript.set_gCullFront(mCullFront);
+ mScript.set_gCullNone(mCullNone);
+ }
+
+ private void initRS() {
+
+ mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
+
+ mMaxModes = mScript.get_gMaxModes();
+
+ initSamplers();
+ initProgramStore();
+ initProgramFragment();
+ initProgramVertex();
+ initFonts();
+ loadImages();
+ initMesh();
+ initProgramRaster();
+ initCustomShaders();
+
+ mRS.bindRootScript(mScript);
+ }
+}
+
+
+
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.java
new file mode 100644
index 0000000..ee7e508
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/RsBenchView.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.perftest;
+
+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 RsBenchView extends RSSurfaceView {
+
+ public RsBenchView(Context context) {
+ super(context);
+ }
+
+ private RenderScriptGL mRS;
+ private RsBenchRS 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);
+ mRS = createRenderScriptGL(sc);
+ mRS.setSurface(holder, w, h);
+ mRender = new RsBenchRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mRS != null) {
+ 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;
+ }
+
+ return ret;
+ }
+}
+
+
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
new file mode 100644
index 0000000..3c92725
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/rsbench.rs
@@ -0,0 +1,786 @@
+// 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.perftest)
+
+#include "rs_graphics.rsh"
+#include "shader_def.rsh"
+
+const int gMaxModes = 26;
+
+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_mesh g10by10Mesh;
+rs_mesh g100by100Mesh;
+rs_mesh gWbyHMesh;
+rs_mesh gTorusMesh;
+
+rs_font gFontSans;
+rs_font gFontSerif;
+rs_font gFontSerifBold;
+rs_font gFontSerifItalic;
+rs_font gFontSerifBoldItalic;
+rs_font gFontMono;
+rs_allocation gTextAlloc;
+
+int gDisplayMode;
+
+rs_sampler gLinearClamp;
+rs_sampler gLinearWrap;
+rs_sampler gMipLinearWrap;
+rs_sampler gMipLinearAniso8;
+rs_sampler gMipLinearAniso15;
+rs_sampler gNearestClamp;
+
+rs_program_raster gCullBack;
+rs_program_raster gCullFront;
+rs_program_raster gCullNone;
+
+// Custom vertex shader compunents
+VertexShaderConstants *gVSConstants;
+FragentShaderConstants *gFSConstants;
+VertexShaderConstants3 *gVSConstPixel;
+FragentShaderConstants3 *gFSConstPixel;
+// Export these out to easily set the inputs to shader
+VertexShaderInputs *gVSInputs;
+// Custom shaders we use for lighting
+rs_program_vertex gProgVertexCustom;
+rs_program_fragment gProgFragmentCustom;
+rs_program_vertex gProgVertexPixelLight;
+rs_program_vertex gProgVertexPixelLightMove;
+rs_program_fragment gProgFragmentPixelLight;
+rs_program_fragment gProgFragmentMultitex;
+
+float gDt = 0;
+
+void init() {
+}
+
+static const char *sampleText = "This is a sample of small text for performace";
+// Offsets for multiple layer of text
+static int textOffsets[] = { 0, 0, -5, -5, 5, 5, -8, -8, 8, 8};
+static float textColors[] = {1.0f, 1.0f, 1.0f, 1.0f,
+ 0.5f, 0.7f, 0.5f, 1.0f,
+ 0.7f, 0.5f, 0.5f, 1.0f,
+ 0.5f, 0.5f, 0.7f, 1.0f,
+ 0.5f, 0.6f, 0.7f, 1.0f,
+};
+
+static void displayFontSamples(int fillNum) {
+
+ rs_font fonts[5];
+ rsSetObject(&fonts[0], gFontSans);
+ rsSetObject(&fonts[1], gFontSerif);
+ rsSetObject(&fonts[2], gFontSerifBold);
+ rsSetObject(&fonts[3], gFontSerifBoldItalic);
+ rsSetObject(&fonts[4], gFontSans);
+
+ uint width = rsgGetWidth();
+ uint height = rsgGetHeight();
+ int left = 0, right = 0, top = 0, bottom = 0;
+ rsgMeasureText(sampleText, &left, &right, &top, &bottom);
+
+ int textHeight = top - bottom;
+ int textWidth = right - left;
+ int numVerticalLines = height / textHeight;
+ int yPos = top;
+
+ int xOffset = 0, yOffset = 0;
+ for(int fillI = 0; fillI < fillNum; fillI ++) {
+ rsgBindFont(fonts[fillI]);
+ xOffset = textOffsets[fillI * 2];
+ yOffset = textOffsets[fillI * 2 + 1];
+ float *colPtr = textColors + fillI * 4;
+ rsgFontColor(colPtr[0], colPtr[1], colPtr[2], colPtr[3]);
+ for (int h = 0; h < 4; h ++) {
+ yPos = top + yOffset;
+ for (int v = 0; v < numVerticalLines; v ++) {
+ rsgDrawText(sampleText, xOffset + textWidth * h, yPos);
+ yPos += textHeight;
+ }
+ }
+ }
+
+ for (int i = 0; i < 5; i ++) {
+ rsClearObject(&fonts[i]);
+ }
+}
+
+static void bindProgramVertexOrtho() {
+ // Default vertex sahder
+ rsgBindProgramVertex(gProgVertex);
+ // Setup the projection matrix
+ rs_matrix4x4 proj;
+ rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
+ 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 = 10 * i, startY = 10 * i;
+ float width = rsgGetWidth() - startX, height = rsgGetHeight() - 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 displayBlendingSamples() {
+ int i;
+
+ bindProgramVertexOrtho();
+ rs_matrix4x4 matrix;
+ rsMatrixLoadIdentity(&matrix);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+
+ rsgBindProgramFragment(gProgFragmentColor);
+
+ rsgBindProgramStore(gProgStoreBlendNone);
+ for (i = 0; i < 3; i ++) {
+ float iPlusOne = (float)(i + 1);
+ rsgProgramFragmentConstantColor(gProgFragmentColor,
+ 0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1);
+ float yPos = 150 * (float)i;
+ rsgDrawRect(0, yPos, 200, yPos + 200, 0);
+ }
+
+ rsgBindProgramStore(gProgStoreBlendAlpha);
+ for (i = 0; i < 3; i ++) {
+ float iPlusOne = (float)(i + 1);
+ rsgProgramFragmentConstantColor(gProgFragmentColor,
+ 0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5);
+ float yPos = 150 * (float)i;
+ rsgDrawRect(150, yPos, 350, yPos + 200, 0);
+ }
+
+ rsgBindProgramStore(gProgStoreBlendAdd);
+ for (i = 0; i < 3; i ++) {
+ float iPlusOne = (float)(i + 1);
+ rsgProgramFragmentConstantColor(gProgFragmentColor,
+ 0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5);
+ float yPos = 150 * (float)i;
+ rsgDrawRect(300, yPos, 500, yPos + 200, 0);
+ }
+
+
+ rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgBindFont(gFontMono);
+ rsgDrawText("No Blending", 10, 50);
+ rsgDrawText("Alpha Blending", 160, 150);
+ rsgDrawText("Additive Blending", 320, 250);
+
+}
+
+static void displayMeshSamples(int meshNum) {
+
+ bindProgramVertexOrtho();
+ rs_matrix4x4 matrix;
+ rsMatrixLoadTranslate(&matrix, rsgGetWidth()/2, rsgGetHeight()/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);
+ }
+}
+
+static void displayTextureSamplers() {
+
+ bindProgramVertexOrtho();
+ rs_matrix4x4 matrix;
+ rsMatrixLoadIdentity(&matrix);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+
+ // Fragment shader with texture
+ rsgBindProgramStore(gProgStoreBlendNone);
+ rsgBindProgramFragment(gProgFragmentTexture);
+ rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+
+ // Linear clamp
+ rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+ float startX = 0, startY = 0;
+ float width = 300, height = 300;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+ startX, startY + height, 0, 0, 1.1,
+ startX + width, startY + height, 0, 1.1, 1.1,
+ startX + width, startY, 0, 1.1, 0);
+
+ // Linear Wrap
+ rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap);
+ startX = 0; startY = 300;
+ width = 300; height = 300;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+ startX, startY + height, 0, 0, 1.1,
+ startX + width, startY + height, 0, 1.1, 1.1,
+ startX + width, startY, 0, 1.1, 0);
+
+ // Nearest
+ rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp);
+ startX = 300; startY = 0;
+ width = 300; height = 300;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+ startX, startY + height, 0, 0, 1.1,
+ startX + width, startY + height, 0, 1.1, 1.1,
+ startX + width, startY, 0, 1.1, 0);
+
+ rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+ startX = 300; startY = 300;
+ width = 300; height = 300;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+ startX, startY + height, 0, 0, 1.5,
+ startX + width, startY + height, 0, 1.5, 1.5,
+ startX + width, startY, 0, 1.5, 0);
+
+ rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgBindFont(gFontMono);
+ rsgDrawText("Filtering: linear clamp", 10, 290);
+ rsgDrawText("Filtering: linear wrap", 10, 590);
+ rsgDrawText("Filtering: nearest clamp", 310, 290);
+ rsgDrawText("Filtering: miplinear wrap", 310, 590);
+}
+
+static float gTorusRotation = 0;
+static void updateModelMatrix(rs_matrix4x4 *matrix, void *buffer) {
+ if (buffer == 0) {
+ rsgProgramVertexLoadModelMatrix(matrix);
+ } else {
+ rsgAllocationSyncAll(rsGetAllocation(buffer));
+ }
+}
+
+static void drawToruses(int numMeshes, rs_matrix4x4 *matrix, void *buffer) {
+
+ if (numMeshes == 1) {
+ rsMatrixLoadTranslate(matrix, 0.0f, 0.0f, -7.5f);
+ rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+ updateModelMatrix(matrix, buffer);
+ rsgDrawMesh(gTorusMesh);
+ return;
+ }
+
+ if (numMeshes == 2) {
+ rsMatrixLoadTranslate(matrix, -1.6f, 0.0f, -7.5f);
+ rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+ updateModelMatrix(matrix, buffer);
+ rsgDrawMesh(gTorusMesh);
+
+ rsMatrixLoadTranslate(matrix, 1.6f, 0.0f, -7.5f);
+ rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+ updateModelMatrix(matrix, buffer);
+ rsgDrawMesh(gTorusMesh);
+ return;
+ }
+
+ float startX = -5.0f;
+ float startY = -1.5f;
+ float startZ = -15.0f;
+ float dist = 3.2f;
+
+ for (int h = 0; h < 4; h ++) {
+ for (int v = 0; v < 2; v ++) {
+ // Position our model on the screen
+ rsMatrixLoadTranslate(matrix, startX + dist * h, startY + dist * v, startZ);
+ rsMatrixRotate(matrix, gTorusRotation, 1.0f, 0.0f, 0.0f);
+ updateModelMatrix(matrix, buffer);
+ rsgDrawMesh(gTorusMesh);
+ }
+ }
+}
+
+
+// Quick hack to get some geometry numbers
+static void displaySimpleGeoSamples(bool useTexture, int numMeshes) {
+ rsgBindProgramVertex(gProgVertex);
+ rsgBindProgramRaster(gCullBack);
+ // Setup the projection matrix with 30 degree field of view
+ rs_matrix4x4 proj;
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+
+ // Fragment shader with texture
+ rsgBindProgramStore(gProgStoreBlendNoneDepth);
+ if (useTexture) {
+ rsgBindProgramFragment(gProgFragmentTexture);
+ } else {
+ rsgBindProgramFragment(gProgFragmentColor);
+ rsgProgramFragmentConstantColor(gProgFragmentColor, 0.1, 0.7, 0.1, 1);
+ }
+ rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+ rsgBindTexture(gProgFragmentTexture, 0, gTexTorus);
+
+ // Apply a rotation to our mesh
+ gTorusRotation += 50.0f * gDt;
+ if (gTorusRotation > 360.0f) {
+ gTorusRotation -= 360.0f;
+ }
+
+ rs_matrix4x4 matrix;
+ drawToruses(numMeshes, &matrix, 0);
+}
+
+float gLight0Rotation = 0;
+float gLight1Rotation = 0;
+
+static void setupCustomShaderLights() {
+ float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f};
+ float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f};
+ float4 light0DiffCol = {0.9f, 0.7f, 0.7f, 1.0f};
+ float4 light0SpecCol = {0.9f, 0.6f, 0.6f, 1.0f};
+ float4 light1DiffCol = {0.5f, 0.5f, 0.9f, 1.0f};
+ float4 light1SpecCol = {0.5f, 0.5f, 0.9f, 1.0f};
+
+ gLight0Rotation += 50.0f * gDt;
+ if (gLight0Rotation > 360.0f) {
+ gLight0Rotation -= 360.0f;
+ }
+ gLight1Rotation -= 50.0f * gDt;
+ if (gLight1Rotation > 360.0f) {
+ gLight1Rotation -= 360.0f;
+ }
+
+ rs_matrix4x4 l0Mat;
+ rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f);
+ light0Pos = rsMatrixMultiply(&l0Mat, light0Pos);
+ rs_matrix4x4 l1Mat;
+ rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f);
+ light1Pos = rsMatrixMultiply(&l1Mat, light1Pos);
+
+ // Set light 0 properties
+ gVSConstants->light0_Posision = light0Pos;
+ gVSConstants->light0_Diffuse = 1.0f;
+ gVSConstants->light0_Specular = 0.5f;
+ gVSConstants->light0_CosinePower = 10.0f;
+ // Set light 1 properties
+ gVSConstants->light1_Posision = light1Pos;
+ gVSConstants->light1_Diffuse = 1.0f;
+ gVSConstants->light1_Specular = 0.7f;
+ gVSConstants->light1_CosinePower = 25.0f;
+ rsgAllocationSyncAll(rsGetAllocation(gVSConstants));
+
+ // Update fragment shader constants
+ // Set light 0 colors
+ gFSConstants->light0_DiffuseColor = light0DiffCol;
+ gFSConstants->light0_SpecularColor = light0SpecCol;
+ // Set light 1 colors
+ gFSConstants->light1_DiffuseColor = light1DiffCol;
+ gFSConstants->light1_SpecularColor = light1SpecCol;
+ rsgAllocationSyncAll(rsGetAllocation(gFSConstants));
+
+ // Set light 0 properties for per pixel lighting
+ gFSConstPixel->light0_Posision = light0Pos;
+ gFSConstPixel->light0_Diffuse = 1.0f;
+ gFSConstPixel->light0_Specular = 0.5f;
+ gFSConstPixel->light0_CosinePower = 10.0f;
+ gFSConstPixel->light0_DiffuseColor = light0DiffCol;
+ gFSConstPixel->light0_SpecularColor = light0SpecCol;
+ // Set light 1 properties
+ gFSConstPixel->light1_Posision = light1Pos;
+ gFSConstPixel->light1_Diffuse = 1.0f;
+ gFSConstPixel->light1_Specular = 0.7f;
+ gFSConstPixel->light1_CosinePower = 25.0f;
+ gFSConstPixel->light1_DiffuseColor = light1DiffCol;
+ gFSConstPixel->light1_SpecularColor = light1SpecCol;
+ rsgAllocationSyncAll(rsGetAllocation(gFSConstPixel));
+}
+
+static void displayCustomShaderSamples(int numMeshes) {
+
+ // Update vertex shader constants
+ // Load model matrix
+ // Apply a rotation to our mesh
+ gTorusRotation += 50.0f * gDt;
+ if (gTorusRotation > 360.0f) {
+ gTorusRotation -= 360.0f;
+ }
+
+ // Setup the projection matrix
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f);
+ setupCustomShaderLights();
+
+ rsgBindProgramVertex(gProgVertexCustom);
+
+ // Fragment shader with texture
+ rsgBindProgramStore(gProgStoreBlendNoneDepth);
+ rsgBindProgramFragment(gProgFragmentCustom);
+ rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp);
+ rsgBindTexture(gProgFragmentCustom, 0, gTexTorus);
+
+ // Use back face culling
+ rsgBindProgramRaster(gCullBack);
+
+ drawToruses(numMeshes, &gVSConstants->model, gVSConstants);
+}
+
+static void displayPixelLightSamples(int numMeshes, bool heavyVertex) {
+
+ // Update vertex shader constants
+ // Load model matrix
+ // Apply a rotation to our mesh
+ gTorusRotation += 30.0f * gDt;
+ if (gTorusRotation > 360.0f) {
+ gTorusRotation -= 360.0f;
+ }
+
+ gVSConstPixel->time = rsUptimeMillis()*0.005;
+
+ // Setup the projection matrix
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&gVSConstPixel->proj, 30.0f, aspect, 0.1f, 100.0f);
+ setupCustomShaderLights();
+
+ if (heavyVertex) {
+ rsgBindProgramVertex(gProgVertexPixelLightMove);
+ } else {
+ rsgBindProgramVertex(gProgVertexPixelLight);
+ }
+
+ // Fragment shader with texture
+ rsgBindProgramStore(gProgStoreBlendNoneDepth);
+ rsgBindProgramFragment(gProgFragmentPixelLight);
+ rsgBindSampler(gProgFragmentPixelLight, 0, gLinearClamp);
+ rsgBindTexture(gProgFragmentPixelLight, 0, gTexTorus);
+
+ // Use back face culling
+ rsgBindProgramRaster(gCullBack);
+
+ drawToruses(numMeshes, &gVSConstPixel->model, gVSConstPixel);
+}
+
+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 = rsgGetWidth() - startX, height = rsgGetHeight() - 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 float gAnisoTime = 0.0f;
+static uint anisoMode = 0;
+static void displayAnisoSample() {
+
+ gAnisoTime += gDt;
+
+ rsgBindProgramVertex(gProgVertex);
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rs_matrix4x4 proj;
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+
+ rs_matrix4x4 matrix;
+ // Fragment shader with texture
+ rsgBindProgramStore(gProgStoreBlendNone);
+ rsgBindProgramFragment(gProgFragmentTexture);
+ rsMatrixLoadTranslate(&matrix, 0.0f, 0.0f, -10.0f);
+ rsMatrixRotate(&matrix, -80, 1.0f, 0.0f, 0.0f);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+
+ rsgBindProgramRaster(gCullNone);
+
+ rsgBindTexture(gProgFragmentTexture, 0, gTexChecker);
+
+ if (gAnisoTime >= 5.0f) {
+ gAnisoTime = 0.0f;
+ anisoMode ++;
+ anisoMode = anisoMode % 3;
+ }
+
+ if (anisoMode == 0) {
+ rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso8);
+ } else if (anisoMode == 1) {
+ rsgBindSampler(gProgFragmentTexture, 0, gMipLinearAniso15);
+ } else {
+ rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap);
+ }
+
+ float startX = -15;
+ float startY = -15;
+ float width = 30;
+ float height = 30;
+ rsgDrawQuadTexCoords(startX, startY, 0, 0, 0,
+ startX, startY + height, 0, 0, 10,
+ startX + width, startY + height, 0, 10, 10,
+ startX + width, startY, 0, 10, 0);
+
+ rsgBindProgramRaster(gCullBack);
+
+ rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgBindFont(gFontMono);
+ if (anisoMode == 0) {
+ rsgDrawText("Anisotropic filtering 8", 10, 40);
+ } else if (anisoMode == 1) {
+ rsgDrawText("Anisotropic filtering 15", 10, 40);
+ } else {
+ rsgDrawText("Miplinear filtering", 10, 40);
+ }
+}
+
+static bool checkInit() {
+
+ static int countdown = 5;
+
+ if (countdown == 0) {
+ gDt = 0;
+ countdown --;
+ }
+ // Perform all the uploads so we only measure rendered time
+ if(countdown > 1) {
+ displayFontSamples(5);
+ displaySingletexFill(true, 3);
+ displayBlendingSamples();
+ displayMeshSamples(0);
+ displayMeshSamples(1);
+ displayMeshSamples(2);
+ displayTextureSamplers();
+ displayMultitextureSample(true, 5);
+ displayAnisoSample();
+ displayPixelLightSamples(1, false);
+ displayPixelLightSamples(1, true);
+ countdown --;
+ rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+
+ // Now use text metrics to center the text
+ uint width = rsgGetWidth();
+ uint height = rsgGetHeight();
+ int left = 0, right = 0, top = 0, bottom = 0;
+
+ rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
+ rsgBindFont(gFontSerifBoldItalic);
+
+ const char* text = "Initializing";
+ rsgMeasureText(text, &left, &right, &top, &bottom);
+ int centeredPosX = width / 2 - (right - left) / 2;
+ int centeredPosY = height / 2 - (top - bottom) / 2;
+ rsgDrawText(text, centeredPosX, centeredPosY);
+
+ return false;
+ }
+
+ return true;
+}
+
+static int frameCount = 0;
+static int totalFramesRendered = 0;
+static int benchMode = 0;
+
+#define testTime 5.0f
+static float curTestTime = testTime;
+
+static const char *testNames[] = {
+ "Finished text fill 1",
+ "Finished text fill 2",
+ "Finished text fill 3",
+ "Finished text fill 4",
+ "Finished text fill 5",
+ "Finished 25.6k geo flat color",
+ "Finished 51.2k geo flat color",
+ "Finished 204.8k geo raster load flat color",
+ "Finished 25.6k geo texture",
+ "Finished 51.2k geo texture",
+ "Finished 204.8k geo raster load texture",
+ "Finished full screen mesh 10 by 10",
+ "Finished full screen mesh 100 by 100",
+ "Finished full screen mesh W / 4 by H / 4",
+ "Finished 25.6k geo heavy vertex",
+ "Finished 51.2k geo heavy vertex",
+ "Finished 204.8k geo raster load heavy vertex",
+ "Finished singletexture 5x fill",
+ "Finished 3tex multitexture 5x fill",
+ "Finished blend singletexture 5x fill",
+ "Finished blend 3tex multitexture 5x fill",
+ "Finished 25.6k geo heavy fragment",
+ "Finished 51.2k geo heavy fragment",
+ "Finished 204.8k geo raster load heavy fragment",
+ "Finished 25.6k geo heavy fragment, heavy vertex",
+ "Finished 51.2k geo heavy fragment, heavy vertex",
+ "Finished 204.8k geo raster load heavy fragment, heavy vertex",
+};
+
+int root(int launchID) {
+
+ gDt = rsGetDt();
+
+ rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ rsgClearDepth(1.0f);
+
+ if(!checkInit()) {
+ return 1;
+ }
+
+ curTestTime -= gDt;
+ if(curTestTime < 0.0f) {
+ float fps = (float)(frameCount) / (testTime - curTestTime);
+ rsDebug(testNames[benchMode], fps);
+ benchMode ++;
+ curTestTime = testTime;
+ totalFramesRendered += frameCount;
+ frameCount = 0;
+ gTorusRotation = 0;
+
+ if (benchMode > gMaxModes) {
+ benchMode = 0;
+ }
+ }
+
+ switch (benchMode) {
+ case 0:
+ displayFontSamples(1);
+ break;
+ case 1:
+ displayFontSamples(2);
+ break;
+ case 2:
+ displayFontSamples(3);
+ break;
+ case 3:
+ displayFontSamples(4);
+ break;
+ case 4:
+ displayFontSamples(5);
+ break;
+ case 5:
+ displaySimpleGeoSamples(false, 1);
+ break;
+ case 6:
+ displaySimpleGeoSamples(false, 2);
+ break;
+ case 7:
+ displaySimpleGeoSamples(false, 8);
+ break;
+ case 8:
+ displaySimpleGeoSamples(true, 1);
+ break;
+ case 9:
+ displaySimpleGeoSamples(true, 2);
+ break;
+ case 10:
+ displaySimpleGeoSamples(true, 8);
+ break;
+ case 11:
+ displayMeshSamples(0);
+ break;
+ case 12:
+ displayMeshSamples(1);
+ break;
+ case 13:
+ displayMeshSamples(2);
+ break;
+ case 14:
+ displayCustomShaderSamples(1);
+ break;
+ case 15:
+ displayCustomShaderSamples(2);
+ break;
+ case 16:
+ displayCustomShaderSamples(8);
+ break;
+ case 17:
+ displaySingletexFill(false, 5);
+ break;
+ case 18:
+ displayMultitextureSample(false, 5);
+ break;
+ case 19:
+ displaySingletexFill(true, 5);
+ break;
+ case 20:
+ displayMultitextureSample(true, 5);
+ break;
+ case 21:
+ displayPixelLightSamples(1, false);
+ break;
+ case 22:
+ displayPixelLightSamples(2, false);
+ break;
+ case 23:
+ displayPixelLightSamples(8, false);
+ break;
+ case 24:
+ displayPixelLightSamples(1, true);
+ break;
+ case 25:
+ displayPixelLightSamples(2, true);
+ break;
+ case 26:
+ displayPixelLightSamples(8, true);
+ break;
+
+ }
+
+ frameCount ++;
+
+ return 1;
+}
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
new file mode 100644
index 0000000..1d77ea9
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/shader_def.rsh
@@ -0,0 +1,83 @@
+// 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.perftest)
+
+typedef struct VertexShaderConstants_s {
+ rs_matrix4x4 model;
+ rs_matrix4x4 proj;
+ float4 light0_Posision;
+ float light0_Diffuse;
+ float light0_Specular;
+ float light0_CosinePower;
+
+ float4 light1_Posision;
+ float light1_Diffuse;
+ float light1_Specular;
+ float light1_CosinePower;
+} VertexShaderConstants;
+
+typedef struct VertexShaderConstants2_s {
+ rs_matrix4x4 model[2];
+ rs_matrix4x4 proj;
+ float4 light_Posision[2];
+ float light_Diffuse[2];
+ float light_Specular[2];
+ float light_CosinePower[2];
+} VertexShaderConstants2;
+
+typedef struct VertexShaderConstants3_s {
+ rs_matrix4x4 model;
+ rs_matrix4x4 proj;
+ float time;
+} VertexShaderConstants3;
+
+
+typedef struct FragentShaderConstants_s {
+ float4 light0_DiffuseColor;
+ float4 light0_SpecularColor;
+
+ float4 light1_DiffuseColor;
+ float4 light1_SpecularColor;
+} FragentShaderConstants;
+
+typedef struct FragentShaderConstants2_s {
+ float4 light_DiffuseColor[2];
+ float4 light_SpecularColor[2];
+} FragentShaderConstants2;
+
+typedef struct FragentShaderConstants3_s {
+ float4 light0_DiffuseColor;
+ float4 light0_SpecularColor;
+ float4 light0_Posision;
+ float light0_Diffuse;
+ float light0_Specular;
+ float light0_CosinePower;
+
+ float4 light1_DiffuseColor;
+ float4 light1_SpecularColor;
+ float4 light1_Posision;
+ float light1_Diffuse;
+ float light1_Specular;
+ float light1_CosinePower;
+} FragentShaderConstants3;
+
+typedef struct VertexShaderInputs_s {
+ float4 position;
+ float3 normal;
+ float2 texture0;
+} VertexShaderInputs;
+