Home | History | Annotate | Download | only in perftest
      1 /*
      2  * Copyright (C) 2010-2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.perftest;
     18 
     19 import java.io.Writer;
     20 import java.io.BufferedWriter;
     21 import java.io.FileWriter;
     22 import java.io.IOException;
     23 import java.io.File;
     24 import java.io.FileOutputStream;
     25 import java.io.OutputStream;
     26 
     27 import android.os.Environment;
     28 import android.content.res.Resources;
     29 import android.renderscript.*;
     30 import android.renderscript.Element.DataKind;
     31 import android.renderscript.Element.DataType;
     32 import android.renderscript.Allocation.MipmapControl;
     33 import android.renderscript.Program.TextureType;
     34 import android.renderscript.RenderScript.RSMessageHandler;
     35 import android.renderscript.Sampler.Value;
     36 import android.renderscript.Mesh.Primitive;
     37 import android.renderscript.Matrix4f;
     38 import android.renderscript.ProgramVertexFixedFunction;
     39 
     40 import android.util.Log;
     41 
     42 
     43 public class RsBenchRS {
     44 
     45     private static final String TAG = "RsBenchRS";
     46     int mWidth;
     47     int mHeight;
     48     int mLoops;
     49     int mCurrentLoop;
     50 
     51     int mBenchmarkDimX;
     52     int mBenchmarkDimY;
     53 
     54     public RsBenchRS() {
     55     }
     56 
     57     public void init(RenderScriptGL rs, Resources res, int width, int height, int loops) {
     58         mRS = rs;
     59         mRes = res;
     60         mWidth = width;
     61         mHeight = height;
     62         mMode = 0;
     63         mLoops = loops;
     64         mCurrentLoop = 0;
     65         mBenchmarkDimX = 1280;
     66         mBenchmarkDimY = 720;
     67         initRS();
     68     }
     69 
     70     private boolean stopTest = false;
     71 
     72     private Resources mRes;
     73     private RenderScriptGL mRS;
     74 
     75     private ProgramStore mProgStoreBlendNone;
     76     private ProgramStore mProgStoreBlendAlpha;
     77 
     78     private ProgramFragment mProgFragmentTexture;
     79     private ProgramFragment mProgFragmentColor;
     80 
     81     private ProgramVertex mProgVertex;
     82     private ProgramVertexFixedFunction.Constants mPVA;
     83     private ProgramVertexFixedFunction.Constants mPvProjectionAlloc;
     84 
     85     private ScriptC_rsbench mScript;
     86 
     87     ScriptField_TestScripts_s.Item[] mIndividualTests;
     88 
     89     int mMode;
     90 
     91     String[] mTestNames;
     92     float[] mLocalTestResults;
     93 
     94     static Allocation createZeroTerminatedAlloc(RenderScript rs,
     95                                                 String str,
     96                                                 int usage) {
     97         byte[] allocArray = null;
     98         try {
     99             allocArray = str.getBytes("UTF-8");
    100             byte[] allocArrayZero = new byte[allocArray.length + 1];
    101             System.arraycopy(allocArray, 0, allocArrayZero, 0, allocArray.length);
    102             allocArrayZero[allocArrayZero.length - 1] = '\0';
    103             Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
    104                                                       allocArrayZero.length, usage);
    105             alloc.copyFrom(allocArrayZero);
    106             return alloc;
    107         }
    108         catch (Exception e) {
    109             throw new RSRuntimeException("Could not convert string to utf-8.");
    110         }
    111 
    112     }
    113 
    114     void appendTests(RsBenchBaseTest testSet) {
    115         ScriptField_TestScripts_s.Item[] newTests = testSet.getTests();
    116         if (mIndividualTests != null) {
    117             ScriptField_TestScripts_s.Item[] combined;
    118             combined = new ScriptField_TestScripts_s.Item[newTests.length + mIndividualTests.length];
    119             System.arraycopy(mIndividualTests, 0, combined, 0, mIndividualTests.length);
    120             System.arraycopy(newTests, 0, combined, mIndividualTests.length, newTests.length);
    121             mIndividualTests = combined;
    122         } else {
    123             mIndividualTests = newTests;
    124         }
    125 
    126         String[] newNames = testSet.getTestNames();
    127         if (mTestNames != null) {
    128             String[] combinedNames;
    129             combinedNames = new String[newNames.length + mTestNames.length];
    130             System.arraycopy(mTestNames, 0, combinedNames, 0, mTestNames.length);
    131             System.arraycopy(newNames, 0, combinedNames, mTestNames.length, newNames.length);
    132             mTestNames = combinedNames;
    133         } else {
    134             mTestNames = newNames;
    135         }
    136     }
    137 
    138     void createTestAllocation() {
    139         int numTests = mIndividualTests.length;
    140         mLocalTestResults = new float[numTests];
    141         ScriptField_TestScripts_s allTests;
    142         allTests = new ScriptField_TestScripts_s(mRS, numTests);
    143         for (int i = 0; i < numTests; i ++) {
    144             allTests.set(mIndividualTests[i], i, false);
    145         }
    146         allTests.copyAll();
    147         mScript.bind_gTestScripts(allTests);
    148     }
    149 
    150     private void saveTestResults() {
    151         String state = Environment.getExternalStorageState();
    152         if (!Environment.MEDIA_MOUNTED.equals(state)) {
    153             Log.v(TAG, "sdcard is read only");
    154             return;
    155         }
    156         File sdCard = Environment.getExternalStorageDirectory();
    157         if (!sdCard.canWrite()) {
    158             Log.v(TAG, "ssdcard is read only");
    159             return;
    160         }
    161 
    162         File resultFile = new File(sdCard, "rsbench_result" + mCurrentLoop + ".csv");
    163         resultFile.setWritable(true, false);
    164 
    165         try {
    166             BufferedWriter results = new BufferedWriter(new FileWriter(resultFile));
    167             for (int i = 0; i < mLocalTestResults.length; i ++) {
    168                 results.write(mTestNames[i] + ", " + mLocalTestResults[i] + ",\n");
    169             }
    170             results.close();
    171             Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
    172         } catch (IOException e) {
    173             Log.v(TAG, "Unable to write result file " + e.getMessage());
    174         }
    175     }
    176 
    177     /**
    178      * Create a message handler to handle message sent from the script
    179      */
    180     protected RSMessageHandler mRsMessage = new RSMessageHandler() {
    181         public void run() {
    182             if (mID == mScript.get_RS_MSG_RESULTS_READY()) {
    183                 for (int i = 0; i < mLocalTestResults.length; i ++) {
    184                     mLocalTestResults[i] = Float.intBitsToFloat(mData[i]);
    185                 }
    186                 saveTestResults();
    187                 if (mLoops > 0) {
    188                     mCurrentLoop ++;
    189                     mCurrentLoop = mCurrentLoop % mLoops;
    190                 }
    191                 return;
    192 
    193             } else if (mID == mScript.get_RS_MSG_TEST_DONE()) {
    194                 synchronized(this) {
    195                     stopTest = true;
    196                     this.notifyAll();
    197                 }
    198                 return;
    199             } else {
    200                 Log.v(TAG, "Perf test got unexpected message");
    201                 return;
    202             }
    203         }
    204     };
    205 
    206     /**
    207      * Wait for message from the script
    208      */
    209     public boolean testIsFinished() {
    210         synchronized(this) {
    211             while (true) {
    212                 if (stopTest) {
    213                     return true;
    214                 } else {
    215                     try {
    216                         this.wait(60*1000);
    217                     } catch (InterruptedException e) {
    218                         e.printStackTrace();
    219                     }
    220                 }
    221             }
    222         }
    223     }
    224 
    225     private void initProgramFragment() {
    226 
    227         ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
    228         texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
    229                               ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
    230         mProgFragmentTexture = texBuilder.create();
    231         mProgFragmentTexture.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
    232 
    233         ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
    234         colBuilder.setVaryingColor(false);
    235         mProgFragmentColor = colBuilder.create();
    236 
    237         mScript.set_gProgFragmentTexture(mProgFragmentTexture);
    238     }
    239 
    240     private void initProgramVertex() {
    241         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
    242         mProgVertex = pvb.create();
    243 
    244         mPVA = new ProgramVertexFixedFunction.Constants(mRS);
    245         ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
    246         Matrix4f proj = new Matrix4f();
    247         proj.loadOrthoWindow(mBenchmarkDimX, mBenchmarkDimY);
    248         mPVA.setProjection(proj);
    249 
    250         mScript.set_gProgVertex(mProgVertex);
    251     }
    252 
    253     private int strlen(byte[] array) {
    254         int count = 0;
    255         while(count < array.length && array[count] != 0) {
    256             count ++;
    257         }
    258         return count;
    259     }
    260 
    261     public void setDebugMode(int num) {
    262         mScript.invoke_setDebugMode(num);
    263     }
    264 
    265     public void setBenchmarkMode(int benchNum) {
    266         mScript.invoke_setBenchmarkMode(benchNum);
    267     }
    268 
    269     public void pause(boolean pause) {
    270         mScript.set_gPauseRendering(pause);
    271     }
    272 
    273     private void initRS() {
    274 
    275         mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
    276         mRS.bindRootScript(mScript);
    277 
    278         mRS.setMessageHandler(mRsMessage);
    279 
    280         mScript.set_gMaxLoops(mLoops);
    281 
    282         initProgramVertex();
    283         initProgramFragment();
    284         mScript.set_gFontSerif(Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8));
    285 
    286         Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
    287         b.setX(mBenchmarkDimX).setY(mBenchmarkDimY);
    288         Allocation offscreen = Allocation.createTyped(mRS,
    289                                                       b.create(),
    290                                                       Allocation.USAGE_GRAPHICS_TEXTURE |
    291                                                       Allocation.USAGE_GRAPHICS_RENDER_TARGET);
    292         mScript.set_gRenderBufferColor(offscreen);
    293 
    294         b = new Type.Builder(mRS,
    295                              Element.createPixel(mRS, DataType.UNSIGNED_16,
    296                              DataKind.PIXEL_DEPTH));
    297         b.setX(mBenchmarkDimX).setY(mBenchmarkDimY);
    298         offscreen = Allocation.createTyped(mRS,
    299                                            b.create(),
    300                                            Allocation.USAGE_GRAPHICS_RENDER_TARGET);
    301         mScript.set_gRenderBufferDepth(offscreen);
    302         mScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS));
    303 
    304         RsBenchBaseTest test = new TextTest();
    305         if (test.init(mRS, mRes)) {
    306             appendTests(test);
    307         }
    308         test = new FillTest();
    309         if (test.init(mRS, mRes)) {
    310             appendTests(test);
    311         }
    312         test = new MeshTest();
    313         if (test.init(mRS, mRes)) {
    314             appendTests(test);
    315         }
    316         test = new TorusTest();
    317         if (test.init(mRS, mRes)) {
    318             appendTests(test);
    319         }
    320         test = new UiTest();
    321         if (test.init(mRS, mRes)) {
    322             appendTests(test);
    323         }
    324         createTestAllocation();
    325 
    326         mScript.set_gLoadComplete(true);
    327     }
    328 }
    329