Home | History | Annotate | Download | only in perftest
      1 // Copyright (C) 2010-2011 The Android Open Source Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #pragma version(1)
     16 
     17 #pragma rs java_package_name(com.android.perftest)
     18 
     19 #include "rs_graphics.rsh"
     20 #include "shader_def.rsh"
     21 #include "subtest_def.rsh"
     22 
     23 /* Message sent from script to renderscript */
     24 const int RS_MSG_TEST_DONE = 100;
     25 const int RS_MSG_RESULTS_READY = 101;
     26 
     27 static const int gMaxModes = 64;
     28 int gMaxLoops = 1;
     29 int gDisplayMode = 1;
     30 
     31 // Allocation to write the results into
     32 static float gResultBuffer[gMaxModes];
     33 
     34 rs_font gFontSerif;
     35 rs_sampler gLinearClamp;
     36 
     37 rs_program_vertex gProgVertex;
     38 rs_program_fragment gProgFragmentTexture;
     39 
     40 rs_allocation gRenderBufferColor;
     41 rs_allocation gRenderBufferDepth;
     42 
     43 VertexShaderInputs *gVSInputs;
     44 
     45 typedef struct TestScripts_s {
     46     rs_allocation testData;
     47     rs_allocation testName;
     48     rs_allocation debugName;
     49     rs_script testScript;
     50 } TestScripts;
     51 TestScripts *gTestScripts;
     52 
     53 bool gLoadComplete = false;
     54 bool gPauseRendering = false;
     55 
     56 static float gDt = 0;
     57 
     58 void init() {
     59 }
     60 
     61 static int gRenderSurfaceW;
     62 static int gRenderSurfaceH;
     63 
     64 static void fillSurfaceParams(TestData *testData) {
     65     testData->renderSurfaceW = gRenderSurfaceW;
     66     testData->renderSurfaceH = gRenderSurfaceH;
     67     testData->dt = gDt;
     68 }
     69 
     70 static void setupOffscreenTarget() {
     71     rsgBindColorTarget(gRenderBufferColor, 0);
     72     rsgBindDepthTarget(gRenderBufferDepth);
     73 }
     74 
     75 static void bindProgramVertexOrtho() {
     76     // Default vertex shader
     77     rsgBindProgramVertex(gProgVertex);
     78     // Setup the projection matrix
     79     rs_matrix4x4 proj;
     80     rsMatrixLoadOrtho(&proj, 0, gRenderSurfaceW, gRenderSurfaceH, 0, -500, 500);
     81     rsgProgramVertexLoadProjectionMatrix(&proj);
     82 }
     83 
     84 static void runSubTest(int index) {
     85     TestData testData;
     86     fillSurfaceParams(&testData);
     87 
     88     rs_allocation null_alloc;
     89     rsForEach(gTestScripts[index].testScript,
     90               gTestScripts[index].testData,
     91               null_alloc,
     92               &testData,
     93               sizeof(testData));
     94 }
     95 
     96 
     97 static bool checkInit() {
     98 
     99     static int countdown = 3;
    100 
    101     // Perform all the uploads so we only measure rendered time
    102     if(countdown > 1) {
    103         int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts));
    104         for(int i = 0; i < testCount; i ++) {
    105             rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
    106             runSubTest(i);
    107             rsgFinish();
    108         }
    109         countdown --;
    110         rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f);
    111 
    112         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    113         rsgBindFont(gFontSerif);
    114         if (countdown == 1) {
    115             rsgDrawText("Rendering", 50, 50);
    116         } else {
    117             rsgDrawText("Initializing", 50, 50);
    118         }
    119 
    120         return false;
    121     }
    122 
    123     return true;
    124 }
    125 
    126 static int benchMode = 0;
    127 static bool benchmarkSingleTest = false;
    128 static int benchSubMode = 0;
    129 static int runningLoops = 0;
    130 static bool sendMsgFlag = false;
    131 
    132 static bool gIsDebugMode = false;
    133 void setDebugMode(int testNumber) {
    134     gIsDebugMode = true;
    135     benchMode = testNumber;
    136     rsgClearAllRenderTargets();
    137 }
    138 
    139 void setBenchmarkMode(int testNumber) {
    140     gIsDebugMode = false;
    141     if (testNumber == -1) {
    142         benchmarkSingleTest = false;
    143         benchMode = 0;
    144     } else {
    145         benchmarkSingleTest = true;
    146         benchMode = testNumber;
    147     }
    148 
    149     runningLoops = 0;
    150 }
    151 
    152 static void drawOffscreenResult(int posX, int posY, int width, int height) {
    153     bindProgramVertexOrtho();
    154 
    155     rs_matrix4x4 matrix;
    156     rsMatrixLoadIdentity(&matrix);
    157     rsgProgramVertexLoadModelMatrix(&matrix);
    158 
    159     rsgBindProgramFragment(gProgFragmentTexture);
    160 
    161     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    162     rsgBindTexture(gProgFragmentTexture, 0, gRenderBufferColor);
    163 
    164     float startX = posX, startY = posY;
    165     rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
    166                          startX, startY + height, 0, 0, 0,
    167                          startX + width, startY + height, 0, 1, 0,
    168                          startX + width, startY, 0, 1, 1);
    169 }
    170 
    171 static void benchmark() {
    172 
    173     gDt = 1.0f / 60.0f;
    174 
    175     rsgFinish();
    176     int64_t start = rsUptimeMillis();
    177 
    178     int drawPos = 0;
    179     int frameCount = 100;
    180     for(int i = 0; i < frameCount; i ++) {
    181         setupOffscreenTarget();
    182         gRenderSurfaceW = rsAllocationGetDimX(gRenderBufferColor);
    183         gRenderSurfaceH = rsAllocationGetDimY(gRenderBufferColor);
    184         rsgClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    185         rsgClearDepth(1.0f);
    186 
    187         runSubTest(benchMode);
    188         rsgClearAllRenderTargets();
    189         gRenderSurfaceW = rsgGetWidth();
    190         gRenderSurfaceH = rsgGetHeight();
    191         int size = 8;
    192         // draw each frame at (8, 3/4 gRenderSurfaceH) with size
    193         drawOffscreenResult((drawPos+=size)%gRenderSurfaceW, (gRenderSurfaceH * 3) / 4, size, size);
    194     }
    195 
    196     rsgFinish();
    197 
    198     int64_t end = rsUptimeMillis();
    199     float fps = (float)(frameCount) / ((float)(end - start)*0.001f);
    200     const char *testName = rsGetElementAt(gTestScripts[benchMode].debugName, 0);
    201     rsDebug(testName, fps);
    202 
    203     gResultBuffer[benchMode] = fps;
    204     int bufferW = rsAllocationGetDimX(gRenderBufferColor);
    205     int bufferH = rsAllocationGetDimY(gRenderBufferColor);
    206 
    207     int quadW = gRenderSurfaceW / 2;
    208     int quadH = (quadW * bufferH) / bufferW;
    209     drawOffscreenResult(0, 0, quadW, quadH);
    210 
    211     int left = 0, right = 0, top = 0, bottom = 0;
    212     uint width = rsgGetWidth();
    213     uint height = rsgGetHeight();
    214     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    215     rsgBindFont(gFontSerif);
    216     rsgMeasureText(gTestScripts[benchMode].testName, &left, &right, &top, &bottom);
    217     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    218     rsgDrawText(gTestScripts[benchMode].testName, 2 -left, height - 2 + bottom);
    219 
    220     if (benchmarkSingleTest) {
    221         return;
    222     }
    223 
    224     benchMode ++;
    225     int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts));
    226     if (benchMode == testCount) {
    227         rsSendToClientBlocking(RS_MSG_RESULTS_READY, gResultBuffer, testCount*sizeof(float));
    228         benchMode = 0;
    229         runningLoops++;
    230         if ((gMaxLoops > 0) && (runningLoops > gMaxLoops) && !sendMsgFlag) {
    231             //Notifiy the test to stop and get results
    232             rsDebug("gMaxLoops and runningLoops: ", gMaxLoops, runningLoops);
    233             rsSendToClientBlocking(RS_MSG_TEST_DONE);
    234             sendMsgFlag = true;
    235         }
    236     }
    237 }
    238 
    239 static void debug() {
    240     gDt = rsGetDt();
    241     runSubTest(benchMode);
    242 }
    243 
    244 int root(void) {
    245     gRenderSurfaceW = rsgGetWidth();
    246     gRenderSurfaceH = rsgGetHeight();
    247     rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    248     rsgClearDepth(1.0f);
    249 
    250     if (!gLoadComplete) {
    251         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    252         rsgBindFont(gFontSerif);
    253         rsgDrawText("Loading", 50, 50);
    254         return 0;
    255     }
    256 
    257     if(!checkInit()) {
    258         return 1;
    259     }
    260 
    261     if (gPauseRendering) {
    262         rsgDrawText("Paused", 50, 50);
    263         return 30;
    264     }
    265     if (gIsDebugMode) {
    266         debug();
    267     } else {
    268         benchmark();
    269     }
    270 
    271     return 1;
    272 }
    273