Home | History | Annotate | Download | only in perftest
      1 /*
      2  * Copyright (C) 2008 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.graphics.Bitmap;
     30 import android.graphics.BitmapFactory;
     31 import android.renderscript.*;
     32 import android.renderscript.Element.DataKind;
     33 import android.renderscript.Element.DataType;
     34 import android.renderscript.Allocation.MipmapControl;
     35 import android.renderscript.Program.TextureType;
     36 import android.renderscript.ProgramStore.DepthFunc;
     37 import android.renderscript.ProgramStore.BlendSrcFunc;
     38 import android.renderscript.ProgramStore.BlendDstFunc;
     39 import android.renderscript.RenderScript.RSMessageHandler;
     40 import android.renderscript.Sampler.Value;
     41 import android.renderscript.Mesh.Primitive;
     42 import android.renderscript.Matrix4f;
     43 import android.renderscript.ProgramVertexFixedFunction;
     44 
     45 import android.util.Log;
     46 
     47 
     48 public class RsBenchRS {
     49 
     50     private static final String TAG = "RsBenchRS";
     51     private static final String SAMPLE_TEXT = "Bench Test";
     52     private static final String LIST_TEXT =
     53       "This is a sample list of text to show in the list view";
     54     private static int PARTICLES_COUNT = 12000;
     55     int mWidth;
     56     int mHeight;
     57     int mLoops;
     58     int mCurrentLoop;
     59 
     60     int mBenchmarkDimX;
     61     int mBenchmarkDimY;
     62 
     63     public RsBenchRS() {
     64     }
     65 
     66     public void init(RenderScriptGL rs, Resources res, int width, int height, int loops) {
     67         mRS = rs;
     68         mRes = res;
     69         mWidth = width;
     70         mHeight = height;
     71         mOptionsARGB.inScaled = false;
     72         mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
     73         mMode = 0;
     74         mMaxModes = 0;
     75         mLoops = loops;
     76         mCurrentLoop = 0;
     77         mBenchmarkDimX = 1280;
     78         mBenchmarkDimY = 720;
     79         initRS();
     80     }
     81 
     82     private boolean stopTest = false;
     83 
     84     private Resources mRes;
     85     private RenderScriptGL mRS;
     86 
     87     private ProgramStore mProgStoreBlendNoneDepth;
     88     private ProgramStore mProgStoreBlendNone;
     89     private ProgramStore mProgStoreBlendAlpha;
     90     private ProgramStore mProgStoreBlendAdd;
     91 
     92     private ProgramFragment mProgFragmentTexture;
     93     private ProgramFragment mProgFragmentColor;
     94 
     95     private ProgramVertex mProgVertex;
     96     private ProgramVertexFixedFunction.Constants mPVA;
     97     private ProgramVertexFixedFunction.Constants mPvProjectionAlloc;
     98 
     99     // Custom shaders
    100     private ProgramVertex mProgVertexCustom;
    101     private ProgramFragment mProgFragmentCustom;
    102     private ProgramFragment mProgFragmentMultitex;
    103     private ProgramVertex mProgVertexPixelLight;
    104     private ProgramVertex mProgVertexPixelLightMove;
    105     private ProgramFragment mProgFragmentPixelLight;
    106     private ScriptField_VertexShaderConstants_s mVSConst;
    107     private ScriptField_FragentShaderConstants_s mFSConst;
    108     private ScriptField_VertexShaderConstants3_s mVSConstPixel;
    109     private ScriptField_FragentShaderConstants3_s mFSConstPixel;
    110 
    111 
    112     private Allocation mTexTorus;
    113     private Allocation mTexOpaque;
    114     private Allocation mTexTransparent;
    115     private Allocation mTexChecker;
    116     private Allocation mTexGlobe;
    117 
    118     private Mesh m10by10Mesh;
    119     private Mesh m100by100Mesh;
    120     private Mesh mWbyHMesh;
    121     private Mesh mTorus;
    122     private Mesh mSingleMesh;
    123     private Mesh mParticlesMesh;
    124 
    125     Font mFontSans;
    126     Font mFontSerif;
    127     private Allocation mTextAlloc;
    128 
    129     private ScriptField_ListAllocs_s mTextureAllocs;
    130     private ScriptField_ListAllocs_s mSampleTextAllocs;
    131     private ScriptField_ListAllocs_s mSampleListViewAllocs;
    132     private ScriptField_VpConsts mPvStarAlloc;
    133 
    134 
    135     private ScriptC_rsbench mScript;
    136     private ScriptC_text_test mTextScript;
    137     private ScriptC_torus_test mTorusScript;
    138 
    139     private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
    140 
    141     int mMode;
    142     int mMaxModes;
    143 
    144     String[] mTestNames;
    145     float[] mLocalTestResults;
    146 
    147     public void onActionDown(int x, int y) {
    148         mMode ++;
    149         mMode = mMode % mMaxModes;
    150         mScript.set_gDisplayMode(mMode);
    151     }
    152 
    153     private void saveTestResults() {
    154         String state = Environment.getExternalStorageState();
    155         if (!Environment.MEDIA_MOUNTED.equals(state)) {
    156             Log.v(TAG, "sdcard is read only");
    157             return;
    158         }
    159         File sdCard = Environment.getExternalStorageDirectory();
    160         if (!sdCard.canWrite()) {
    161             Log.v(TAG, "ssdcard is read only");
    162             return;
    163         }
    164 
    165         File resultFile = new File(sdCard, "rsbench_result" + mCurrentLoop + ".csv");
    166         resultFile.setWritable(true, false);
    167 
    168         try {
    169             BufferedWriter results = new BufferedWriter(new FileWriter(resultFile));
    170             for (int i = 0; i < mLocalTestResults.length; i ++) {
    171                 results.write(mTestNames[i] + ", " + mLocalTestResults[i] + ",\n");
    172             }
    173             results.close();
    174             Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
    175         } catch (IOException e) {
    176             Log.v(TAG, "Unable to write result file " + e.getMessage());
    177         }
    178     }
    179 
    180     /**
    181      * Create a message handler to handle message sent from the script
    182      */
    183     protected RSMessageHandler mRsMessage = new RSMessageHandler() {
    184         public void run() {
    185             if (mID == mScript.get_RS_MSG_RESULTS_READY()) {
    186                 for (int i = 0; i < mLocalTestResults.length; i ++) {
    187                     mLocalTestResults[i] = Float.intBitsToFloat(mData[i]);
    188                 }
    189                 saveTestResults();
    190                 if (mLoops > 0) {
    191                     mCurrentLoop ++;
    192                     mCurrentLoop = mCurrentLoop % mLoops;
    193                 }
    194                 return;
    195 
    196             } else if (mID == mScript.get_RS_MSG_TEST_DONE()) {
    197                 synchronized(this) {
    198                     stopTest = true;
    199                     this.notifyAll();
    200                 }
    201                 return;
    202             } else {
    203                 Log.v(TAG, "Perf test got unexpected message");
    204                 return;
    205             }
    206         }
    207     };
    208 
    209     /**
    210      * Wait for message from the script
    211      */
    212     public boolean testIsFinished() {
    213         synchronized(this) {
    214             while (true) {
    215                 if (stopTest) {
    216                     return true;
    217                 } else {
    218                     try {
    219                         this.wait(60*1000);
    220                     } catch (InterruptedException e) {
    221                         e.printStackTrace();
    222                     }
    223                 }
    224             }
    225         }
    226     }
    227 
    228     ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
    229         ProgramStore.Builder builder = new ProgramStore.Builder(rs);
    230         builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
    231         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
    232         builder.setDitherEnabled(false);
    233         builder.setDepthMaskEnabled(false);
    234         return builder.create();
    235     }
    236 
    237     private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) {
    238 
    239         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
    240                                            2, Mesh.TriangleMeshBuilder.TEXTURE_0);
    241 
    242         for (int y = 0; y <= hResolution; y++) {
    243             final float normalizedY = (float)y / hResolution;
    244             final float yOffset = (normalizedY - 0.5f) * height;
    245             for (int x = 0; x <= wResolution; x++) {
    246                 float normalizedX = (float)x / wResolution;
    247                 float xOffset = (normalizedX - 0.5f) * width;
    248                 tmb.setTexture((float)x % 2, (float)y % 2);
    249                 tmb.addVertex(xOffset, yOffset);
    250              }
    251         }
    252 
    253         for (int y = 0; y < hResolution; y++) {
    254             final int curY = y * (wResolution + 1);
    255             final int belowY = (y + 1) * (wResolution + 1);
    256             for (int x = 0; x < wResolution; x++) {
    257                 int curV = curY + x;
    258                 int belowV = belowY + x;
    259                 tmb.addTriangle(curV, belowV, curV + 1);
    260                 tmb.addTriangle(belowV, belowV + 1, curV + 1);
    261             }
    262         }
    263 
    264         return tmb.create(true);
    265     }
    266 
    267     /**
    268      * Create a mesh with a single quad for the given width and height.
    269      */
    270     private Mesh getSingleMesh(float width, float height) {
    271         Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
    272                                            2, Mesh.TriangleMeshBuilder.TEXTURE_0);
    273         float xOffset = width/2;
    274         float yOffset = height/2;
    275         tmb.setTexture(0, 0);
    276         tmb.addVertex(-1.0f * xOffset, -1.0f * yOffset);
    277         tmb.setTexture(1, 0);
    278         tmb.addVertex(xOffset, -1.0f * yOffset);
    279         tmb.setTexture(1, 1);
    280         tmb.addVertex(xOffset, yOffset);
    281         tmb.setTexture(0, 1);
    282         tmb.addVertex(-1.0f * xOffset, yOffset);
    283         tmb.addTriangle(0, 3, 1);
    284         tmb.addTriangle(1, 3, 2);
    285         return tmb.create(true);
    286     }
    287 
    288     private void initProgramStore() {
    289         // Use stock the stock program store object
    290         mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS);
    291         mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
    292 
    293         // Create a custom program store
    294         ProgramStore.Builder builder = new ProgramStore.Builder(mRS);
    295         builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
    296         builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
    297                              ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
    298         builder.setDitherEnabled(false);
    299         builder.setDepthMaskEnabled(false);
    300         mProgStoreBlendAlpha = builder.create();
    301 
    302         mProgStoreBlendAdd = BLEND_ADD_DEPTH_NONE(mRS);
    303 
    304         mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
    305 
    306         mScript.set_gProgStoreBlendNone(mProgStoreBlendNone);
    307         mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha);
    308         mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd);
    309 
    310         // For GALAXY
    311         builder = new ProgramStore.Builder(mRS);
    312         builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
    313         mRS.bindProgramStore(builder.create());
    314 
    315         builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE);
    316         mScript.set_gPSLights(builder.create());
    317 
    318     }
    319 
    320     private void initProgramFragment() {
    321 
    322         ProgramFragmentFixedFunction.Builder texBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
    323         texBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
    324                               ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
    325         mProgFragmentTexture = texBuilder.create();
    326         mProgFragmentTexture.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
    327 
    328         ProgramFragmentFixedFunction.Builder colBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
    329         colBuilder.setVaryingColor(false);
    330         mProgFragmentColor = colBuilder.create();
    331 
    332         mScript.set_gProgFragmentColor(mProgFragmentColor);
    333 
    334         mScript.set_gProgFragmentTexture(mProgFragmentTexture);
    335 
    336 
    337 
    338         // For Galaxy live wallpaper drawing
    339         ProgramFragmentFixedFunction.Builder builder = new ProgramFragmentFixedFunction.Builder(mRS);
    340         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
    341                            ProgramFragmentFixedFunction.Builder.Format.RGB, 0);
    342         ProgramFragment pfb = builder.create();
    343         pfb.bindSampler(Sampler.WRAP_NEAREST(mRS), 0);
    344         mScript.set_gPFBackground(pfb);
    345 
    346         builder = new ProgramFragmentFixedFunction.Builder(mRS);
    347         builder.setPointSpriteTexCoordinateReplacement(true);
    348         builder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.MODULATE,
    349                            ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
    350         builder.setVaryingColor(true);
    351         ProgramFragment pfs = builder.create();
    352         pfs.bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
    353         mScript.set_gPFStars(pfs);
    354 
    355     }
    356 
    357     private Matrix4f getProjectionNormalized(int w, int h) {
    358       // range -1,1 in the narrow axis at z = 0.
    359       Matrix4f m1 = new Matrix4f();
    360       Matrix4f m2 = new Matrix4f();
    361 
    362       if(w > h) {
    363           float aspect = ((float)w) / h;
    364           m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
    365       } else {
    366           float aspect = ((float)h) / w;
    367           m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
    368       }
    369 
    370       m2.loadRotate(180, 0, 1, 0);
    371       m1.loadMultiply(m1, m2);
    372 
    373       m2.loadScale(-2, 2, 1);
    374       m1.loadMultiply(m1, m2);
    375 
    376       m2.loadTranslate(0, 0, 2);
    377       m1.loadMultiply(m1, m2);
    378       return m1;
    379   }
    380 
    381     private void updateProjectionMatrices() {
    382       Matrix4f projNorm = getProjectionNormalized(mBenchmarkDimX, mBenchmarkDimY);
    383       ScriptField_VpConsts.Item i = new ScriptField_VpConsts.Item();
    384       i.Proj = projNorm;
    385       i.MVP = projNorm;
    386       mPvStarAlloc.set(i, 0, true);
    387       mPvProjectionAlloc.setProjection(projNorm);
    388   }
    389 
    390     private void initProgramVertex() {
    391         ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
    392         mProgVertex = pvb.create();
    393 
    394         mPVA = new ProgramVertexFixedFunction.Constants(mRS);
    395         ((ProgramVertexFixedFunction)mProgVertex).bindConstants(mPVA);
    396         Matrix4f proj = new Matrix4f();
    397         proj.loadOrthoWindow(mBenchmarkDimX, mBenchmarkDimY);
    398         mPVA.setProjection(proj);
    399 
    400         mScript.set_gProgVertex(mProgVertex);
    401 
    402 
    403         // For galaxy live wallpaper
    404         mPvStarAlloc = new ScriptField_VpConsts(mRS, 1);
    405         mScript.bind_vpConstants(mPvStarAlloc);
    406         mPvProjectionAlloc = new ProgramVertexFixedFunction.Constants(mRS);
    407         updateProjectionMatrices();
    408 
    409         pvb = new ProgramVertexFixedFunction.Builder(mRS);
    410         ProgramVertex pvbp = pvb.create();
    411         ((ProgramVertexFixedFunction)pvbp).bindConstants(mPvProjectionAlloc);
    412         mScript.set_gPVBkProj(pvbp);
    413 
    414         ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
    415         String t =  "varying vec4 varColor;\n" +
    416                     "varying vec2 varTex0;\n" +
    417                     "void main() {\n" +
    418                     "  float dist = ATTRIB_position.y;\n" +
    419                     "  float angle = ATTRIB_position.x;\n" +
    420                     "  float x = dist * sin(angle);\n" +
    421                     "  float y = dist * cos(angle) * 0.892;\n" +
    422                     "  float p = dist * 5.5;\n" +
    423                     "  float s = cos(p);\n" +
    424                     "  float t = sin(p);\n" +
    425                     "  vec4 pos;\n" +
    426                     "  pos.x = t * x + s * y;\n" +
    427                     "  pos.y = s * x - t * y;\n" +
    428                     "  pos.z = ATTRIB_position.z;\n" +
    429                     "  pos.w = 1.0;\n" +
    430                     "  gl_Position = UNI_MVP * pos;\n" +
    431                     "  gl_PointSize = ATTRIB_color.a * 10.0;\n" +
    432                     "  varColor.rgb = ATTRIB_color.rgb;\n" +
    433                     "  varColor.a = 1.0;\n" +
    434                     "}\n";
    435         sb.setShader(t);
    436         sb.addInput(mParticlesMesh.getVertexAllocation(0).getType().getElement());
    437         sb.addConstant(mPvStarAlloc.getType());
    438         ProgramVertex pvs = sb.create();
    439         pvs.bindConstants(mPvStarAlloc.getAllocation(), 0);
    440         mScript.set_gPVStars(pvs);
    441     }
    442 
    443     private void initCustomShaders() {
    444         mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1);
    445         mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1);
    446 
    447 
    448         mVSConstPixel = new ScriptField_VertexShaderConstants3_s(mRS, 1);
    449         mFSConstPixel = new ScriptField_FragentShaderConstants3_s(mRS, 1);
    450 
    451 
    452         // Initialize the shader builder
    453         ProgramVertex.Builder pvbCustom = new ProgramVertex.Builder(mRS);
    454         // Specify the resource that contains the shader string
    455         pvbCustom.setShader(mRes, R.raw.shaderv);
    456         // Use a script field to specify the input layout
    457         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
    458         // Define the constant input layout
    459         pvbCustom.addConstant(mVSConst.getAllocation().getType());
    460         mProgVertexCustom = pvbCustom.create();
    461         // Bind the source of constant data
    462         mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0);
    463 
    464         ProgramFragment.Builder pfbCustom = new ProgramFragment.Builder(mRS);
    465         // Specify the resource that contains the shader string
    466         pfbCustom.setShader(mRes, R.raw.shaderf);
    467         // Tell the builder how many textures we have
    468         pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
    469         // Define the constant input layout
    470         pfbCustom.addConstant(mFSConst.getAllocation().getType());
    471         mProgFragmentCustom = pfbCustom.create();
    472         // Bind the source of constant data
    473         mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0);
    474 
    475         pvbCustom = new ProgramVertex.Builder(mRS);
    476         pvbCustom.setShader(mRes, R.raw.shader2v);
    477         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
    478         pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
    479         mProgVertexPixelLight = pvbCustom.create();
    480         mProgVertexPixelLight.bindConstants(mVSConstPixel.getAllocation(), 0);
    481 
    482         pvbCustom = new ProgramVertex.Builder(mRS);
    483         pvbCustom.setShader(mRes, R.raw.shader2movev);
    484         pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS));
    485         pvbCustom.addConstant(mVSConstPixel.getAllocation().getType());
    486         mProgVertexPixelLightMove = pvbCustom.create();
    487         mProgVertexPixelLightMove.bindConstants(mVSConstPixel.getAllocation(), 0);
    488 
    489         pfbCustom = new ProgramFragment.Builder(mRS);
    490         pfbCustom.setShader(mRes, R.raw.shader2f);
    491         pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
    492         pfbCustom.addConstant(mFSConstPixel.getAllocation().getType());
    493         mProgFragmentPixelLight = pfbCustom.create();
    494         mProgFragmentPixelLight.bindConstants(mFSConstPixel.getAllocation(), 0);
    495 
    496         pfbCustom = new ProgramFragment.Builder(mRS);
    497         pfbCustom.setShader(mRes, R.raw.multitexf);
    498         for (int texCount = 0; texCount < 3; texCount ++) {
    499             pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
    500         }
    501         mProgFragmentMultitex = pfbCustom.create();
    502 
    503 
    504         mScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
    505     }
    506 
    507     private Allocation loadTextureRGB(int id) {
    508         return Allocation.createFromBitmapResource(mRS, mRes, id,
    509                 Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
    510                 Allocation.USAGE_GRAPHICS_TEXTURE);
    511     }
    512 
    513     private Allocation loadTextureARGB(int id) {
    514         Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB);
    515         return Allocation.createFromBitmap(mRS, b,
    516                 Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
    517                 Allocation.USAGE_GRAPHICS_TEXTURE);
    518     }
    519 
    520     private void loadImages() {
    521         mTexTorus = loadTextureRGB(R.drawable.torusmap);
    522         mTexOpaque = loadTextureRGB(R.drawable.data);
    523         mTexTransparent = loadTextureARGB(R.drawable.leaf);
    524         mTexChecker = loadTextureRGB(R.drawable.checker);
    525         mTexGlobe = loadTextureRGB(R.drawable.globe);
    526 
    527         mScript.set_gTexTorus(mTexTorus);
    528         mScript.set_gTexOpaque(mTexOpaque);
    529         mScript.set_gTexTransparent(mTexTransparent);
    530         mScript.set_gTexChecker(mTexChecker);
    531         mScript.set_gTexGlobe(mTexGlobe);
    532 
    533         // For Galaxy live wallpaper
    534         mScript.set_gTSpace(loadTextureRGB(R.drawable.space));
    535         mScript.set_gTLight1(loadTextureRGB(R.drawable.light1));
    536         mScript.set_gTFlares(loadTextureARGB(R.drawable.flares));
    537     }
    538 
    539     private void initFonts() {
    540         // Sans font by family name
    541         mFontSans = Font.create(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8);
    542         mFontSerif = Font.create(mRS, mRes, "serif", Font.Style.NORMAL, 8);
    543         // Create fonts by family and style
    544 
    545         mTextAlloc = Allocation.createFromString(mRS, "String from allocation", Allocation.USAGE_SCRIPT);
    546 
    547         mScript.set_gFontSans(mFontSans);
    548         mScript.set_gFontSerif(mFontSerif);
    549     }
    550 
    551     private void createParticlesMesh() {
    552         ScriptField_Particle p = new ScriptField_Particle(mRS, PARTICLES_COUNT);
    553 
    554         final Mesh.AllocationBuilder meshBuilder = new Mesh.AllocationBuilder(mRS);
    555         meshBuilder.addVertexAllocation(p.getAllocation());
    556         final int vertexSlot = meshBuilder.getCurrentVertexTypeIndex();
    557         meshBuilder.addIndexSetType(Primitive.POINT);
    558         mParticlesMesh = meshBuilder.create();
    559 
    560         mScript.set_gParticlesMesh(mParticlesMesh);
    561         mScript.bind_Particles(p);
    562     }
    563 
    564     private void initMesh() {
    565         m10by10Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 10, 10);
    566         mScript.set_g10by10Mesh(m10by10Mesh);
    567         m100by100Mesh = getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, 100, 100);
    568         mScript.set_g100by100Mesh(m100by100Mesh);
    569         mWbyHMesh= getMbyNMesh(mBenchmarkDimX, mBenchmarkDimY, mBenchmarkDimX/4, mBenchmarkDimY/4);
    570         mScript.set_gWbyHMesh(mWbyHMesh);
    571         mSingleMesh = getSingleMesh(1, 1);  // a unit size mesh
    572         mScript.set_gSingleMesh(mSingleMesh);
    573 
    574         FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus);
    575         FileA3D.IndexEntry entry = model.getIndexEntry(0);
    576         if (entry == null || entry.getEntryType() != FileA3D.EntryType.MESH) {
    577             Log.e("rs", "could not load model");
    578         } else {
    579             mTorus = (Mesh)entry.getObject();
    580         }
    581 
    582         createParticlesMesh();
    583     }
    584 
    585     private void initSamplers() {
    586         mScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS));
    587         mScript.set_gLinearWrap(Sampler.WRAP_LINEAR(mRS));
    588         mScript.set_gMipLinearWrap(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS));
    589         mScript.set_gNearestClamp(Sampler.CLAMP_NEAREST(mRS));
    590     }
    591 
    592     private void initProgramRaster() {
    593         mScript.set_gCullBack(ProgramRaster.CULL_BACK(mRS));
    594         mScript.set_gCullFront(ProgramRaster.CULL_FRONT(mRS));
    595         mScript.set_gCullNone(ProgramRaster.CULL_NONE(mRS));
    596     }
    597 
    598     private int strlen(byte[] array) {
    599         int count = 0;
    600         while(count < array.length && array[count] != 0) {
    601             count ++;
    602         }
    603         return count;
    604     }
    605 
    606     private void prepareTestData() {
    607         mTestNames = new String[mMaxModes];
    608         mLocalTestResults = new float[mMaxModes];
    609         int scratchSize = 1024;
    610         Allocation scratch = Allocation.createSized(mRS, Element.U8(mRS), scratchSize);
    611         byte[] tmp = new byte[scratchSize];
    612         mScript.bind_gStringBuffer(scratch);
    613         for (int i = 0; i < mMaxModes; i ++) {
    614             mScript.invoke_getTestName(i);
    615             scratch.copyTo(tmp);
    616             int len = strlen(tmp);
    617             mTestNames[i] = new String(tmp, 0, len);
    618         }
    619     }
    620 
    621     public void setDebugMode(int num) {
    622         mScript.invoke_setDebugMode(num);
    623     }
    624 
    625     public void setBenchmarkMode() {
    626         mScript.invoke_setBenchmarkMode();
    627     }
    628 
    629     void initTextScript() {
    630         mTextScript = new ScriptC_text_test(mRS, mRes, R.raw.text_test);
    631         mTextScript.set_gFontSans(mFontSans);
    632         mTextScript.set_gFontSerif(mFontSerif);
    633     }
    634 
    635     void initTorusScript() {
    636         mTorusScript = new ScriptC_torus_test(mRS, mRes, R.raw.torus_test);
    637         mTorusScript.set_gCullFront(ProgramRaster.CULL_FRONT(mRS));
    638         mTorusScript.set_gCullBack(ProgramRaster.CULL_BACK(mRS));
    639         mTorusScript.set_gLinearClamp(Sampler.CLAMP_LINEAR(mRS));
    640         mTorusScript.set_gTorusMesh(mTorus);
    641         mTorusScript.set_gTexTorus(mTexTorus);
    642         mTorusScript.set_gProgVertexCustom(mProgVertexCustom);
    643         mTorusScript.set_gProgFragmentCustom(mProgFragmentCustom);
    644         mTorusScript.set_gProgVertexPixelLight(mProgVertexPixelLight);
    645         mTorusScript.set_gProgVertexPixelLightMove(mProgVertexPixelLightMove);
    646         mTorusScript.set_gProgFragmentPixelLight(mProgFragmentPixelLight);
    647         mTorusScript.bind_gVSConstPixel(mVSConstPixel);
    648         mTorusScript.bind_gFSConstPixel(mFSConstPixel);
    649         mTorusScript.bind_gVSConstants(mVSConst);
    650         mTorusScript.bind_gFSConstants(mFSConst);
    651         mTorusScript.set_gProgVertex(mProgVertex);
    652         mTorusScript.set_gProgFragmentTexture(mProgFragmentTexture);
    653         mTorusScript.set_gProgFragmentColor(mProgFragmentColor);
    654         mTorusScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth);
    655     }
    656 
    657     private void initRS() {
    658 
    659         mScript = new ScriptC_rsbench(mRS, mRes, R.raw.rsbench);
    660 
    661 
    662         mRS.setMessageHandler(mRsMessage);
    663 
    664         mMaxModes = mScript.get_gMaxModes();
    665         mScript.set_gMaxLoops(mLoops);
    666 
    667         prepareTestData();
    668 
    669         initSamplers();
    670         initMesh();
    671         initProgramVertex();
    672         initProgramStore();
    673         initProgramFragment();
    674         initFonts();
    675         loadImages();
    676         initProgramRaster();
    677         initCustomShaders();
    678 
    679         Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
    680         b.setX(mBenchmarkDimX).setY(mBenchmarkDimY);
    681         Allocation offscreen = Allocation.createTyped(mRS,
    682                                                       b.create(),
    683                                                       Allocation.USAGE_GRAPHICS_TEXTURE |
    684                                                       Allocation.USAGE_GRAPHICS_RENDER_TARGET);
    685         mScript.set_gRenderBufferColor(offscreen);
    686 
    687         b = new Type.Builder(mRS,
    688                              Element.createPixel(mRS, DataType.UNSIGNED_16,
    689                              DataKind.PIXEL_DEPTH));
    690         b.setX(mBenchmarkDimX).setY(mBenchmarkDimY);
    691         offscreen = Allocation.createTyped(mRS,
    692                                            b.create(),
    693                                            Allocation.USAGE_GRAPHICS_RENDER_TARGET);
    694         mScript.set_gRenderBufferDepth(offscreen);
    695 
    696         mTextureAllocs = new ScriptField_ListAllocs_s(mRS, 100);
    697         for (int i = 0; i < 100; i++) {
    698             ScriptField_ListAllocs_s.Item texElem = new ScriptField_ListAllocs_s.Item();
    699             texElem.item = loadTextureRGB(R.drawable.globe);
    700             mTextureAllocs.set(texElem, i, false);
    701         }
    702         mTextureAllocs.copyAll();
    703         mScript.bind_gTexList100(mTextureAllocs);
    704 
    705         mSampleTextAllocs = new ScriptField_ListAllocs_s(mRS, 100);
    706         for (int i = 0; i < 100; i++) {
    707             ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item();
    708             textElem.item = Allocation.createFromString(mRS, SAMPLE_TEXT, Allocation.USAGE_SCRIPT);
    709             mSampleTextAllocs.set(textElem, i, false);
    710         }
    711         mSampleTextAllocs.copyAll();
    712         mScript.bind_gSampleTextList100(mSampleTextAllocs);
    713 
    714         mSampleListViewAllocs = new ScriptField_ListAllocs_s(mRS, 1000);
    715         for (int i = 0; i < 1000; i++) {
    716             ScriptField_ListAllocs_s.Item textElem = new ScriptField_ListAllocs_s.Item();
    717             textElem.item = Allocation.createFromString(mRS, LIST_TEXT, Allocation.USAGE_SCRIPT);
    718             mSampleListViewAllocs.set(textElem, i, false);
    719         }
    720         mSampleListViewAllocs.copyAll();
    721         mScript.bind_gListViewText(mSampleListViewAllocs);
    722 
    723         initTextScript();
    724         initTorusScript();
    725 
    726         mScript.set_gFontScript(mTextScript);
    727         mScript.set_gTorusScript(mTorusScript);
    728         mScript.set_gDummyAlloc(Allocation.createSized(mRS, Element.I32(mRS), 1));
    729 
    730         mRS.bindRootScript(mScript);
    731     }
    732 }
    733