| /* |
| * 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. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT 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.io.BufferedWriter; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.OutputStream; |
| |
| import android.os.Environment; |
| import android.content.res.Resources; |
| 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.Sampler.Value; |
| import android.renderscript.Mesh.Primitive; |
| import android.renderscript.Matrix4f; |
| import android.renderscript.ProgramVertexFixedFunction; |
| |
| import android.util.Log; |
| |
| |
| public class RsBenchRS { |
| |
| private static final String TAG = "RsBenchRS"; |
| int mWidth; |
| int mHeight; |
| int mLoops; |
| int mCurrentLoop; |
| |
| int mBenchmarkDimX; |
| int mBenchmarkDimY; |
| |
| public RsBenchRS() { |
| } |
| |
| public void init(RenderScriptGL rs, Resources res, int width, int height, int loops) { |
| mRS = rs; |
| mRes = res; |
| mWidth = width; |
| mHeight = height; |
| mMode = 0; |
| mLoops = loops; |
| mCurrentLoop = 0; |
| mBenchmarkDimX = 1280; |
| mBenchmarkDimY = 720; |
| initRS(); |
| } |
| |
| private boolean stopTest = false; |
| |
| private Resources mRes; |
| private RenderScriptGL mRS; |
| |
| private ProgramStore mProgStoreBlendNone; |
| private ProgramStore mProgStoreBlendAlpha; |
| |
| private ProgramFragment mProgFragmentTexture; |
| private ProgramFragment mProgFragmentColor; |
| |
| private ProgramVertex mProgVertex; |
| private ProgramVertexFixedFunction.Constants mPVA; |
| private ProgramVertexFixedFunction.Constants mPvProjectionAlloc; |
| |
| private ScriptC_rsbench mScript; |
| |
| ScriptField_TestScripts_s.Item[] mIndividualTests; |
| |
| int mMode; |
| |
| String[] mTestNames; |
| float[] mLocalTestResults; |
| |
| 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() { |
| String state = Environment.getExternalStorageState(); |
| if (!Environment.MEDIA_MOUNTED.equals(state)) { |
| Log.v(TAG, "sdcard is read only"); |
| return; |
| } |
| File sdCard = Environment.getExternalStorageDirectory(); |
| if (!sdCard.canWrite()) { |
| Log.v(TAG, "ssdcard is read only"); |
| return; |
| } |
| |
| File resultFile = new File(sdCard, "rsbench_result" + mCurrentLoop + ".csv"); |
| resultFile.setWritable(true, false); |
| |
| try { |
| BufferedWriter results = new BufferedWriter(new FileWriter(resultFile)); |
| for (int i = 0; i < mLocalTestResults.length; i ++) { |
| results.write(mTestNames[i] + ", " + mLocalTestResults[i] + ",\n"); |
| } |
| results.close(); |
| Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath()); |
| } catch (IOException e) { |
| Log.v(TAG, "Unable to write result file " + e.getMessage()); |
| } |
| } |
| |
| /** |
| * Create a message handler to handle message sent from the script |
| */ |
| protected RSMessageHandler mRsMessage = new RSMessageHandler() { |
| public void run() { |
| if (mID == mScript.get_RS_MSG_RESULTS_READY()) { |
| for (int i = 0; i < mLocalTestResults.length; i ++) { |
| mLocalTestResults[i] = Float.intBitsToFloat(mData[i]); |
| } |
| saveTestResults(); |
| if (mLoops > 0) { |
| mCurrentLoop ++; |
| mCurrentLoop = mCurrentLoop % mLoops; |
| } |
| return; |
| |
| } else if (mID == mScript.get_RS_MSG_TEST_DONE()) { |
| synchronized(this) { |
| stopTest = true; |
| this.notifyAll(); |
| } |
| return; |
| } else { |
| Log.v(TAG, "Perf test got unexpected message"); |
| return; |
| } |
| } |
| }; |
| |
| /** |
| * Wait for message from the script |
| */ |
| public boolean testIsFinished() { |
| synchronized(this) { |
| while (true) { |
| if (stopTest) { |
| return true; |
| } else { |
| try { |
| this.wait(60*1000); |
| } catch (InterruptedException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| } |
| } |
| |
| 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(Sampler.CLAMP_LINEAR(mRS), 0); |
| |
| ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS); |
| colBuilder.setVaryingColor(false); |
| mProgFragmentColor = colBuilder.create(); |
| |
| 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(mBenchmarkDimX, mBenchmarkDimY); |
| mPVA.setProjection(proj); |
| |
| mScript.set_gProgVertex(mProgVertex); |
| } |
| |
| private int strlen(byte[] array) { |
| int count = 0; |
| while(count < array.length && array[count] != 0) { |
| count ++; |
| } |
| return count; |
| } |
| |
| public void setDebugMode(int num) { |
| mScript.invoke_setDebugMode(num); |
| } |
| |
| public void setBenchmarkMode(int benchNum) { |
| mScript.invoke_setBenchmarkMode(benchNum); |
| } |
| |
| 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); |
| |
| mScript.set_gMaxLoops(mLoops); |
| |
| initProgramVertex(); |
| initProgramFragment(); |
| 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); |
| Allocation offscreen = Allocation.createTyped(mRS, |
| b.create(), |
| Allocation.USAGE_GRAPHICS_TEXTURE | |
| Allocation.USAGE_GRAPHICS_RENDER_TARGET); |
| mScript.set_gRenderBufferColor(offscreen); |
| |
| b = new Type.Builder(mRS, |
| Element.createPixel(mRS, DataType.UNSIGNED_16, |
| DataKind.PIXEL_DEPTH)); |
| b.setX(mBenchmarkDimX).setY(mBenchmarkDimY); |
| offscreen = Allocation.createTyped(mRS, |
| b.create(), |
| Allocation.USAGE_GRAPHICS_RENDER_TARGET); |
| mScript.set_gRenderBufferDepth(offscreen); |
| mScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS)); |
| |
| RsBenchBaseTest test = new TextTest(); |
| if (test.init(mRS, mRes)) { |
| appendTests(test); |
| } |
| test = new FillTest(); |
| if (test.init(mRS, mRes)) { |
| appendTests(test); |
| } |
| test = new MeshTest(); |
| if (test.init(mRS, mRes)) { |
| appendTests(test); |
| } |
| test = new TorusTest(); |
| if (test.init(mRS, mRes)) { |
| appendTests(test); |
| } |
| test = new UiTest(); |
| if (test.init(mRS, mRes)) { |
| appendTests(test); |
| } |
| createTestAllocation(); |
| |
| mScript.set_gLoadComplete(true); |
| } |
| } |