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 = {0};
     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 runningLoops = 0;
    129 static bool sendMsgFlag = false;
    130 
    131 static bool gIsDebugMode = false;
    132 void setDebugMode(int testNumber) {
    133     gIsDebugMode = true;
    134     benchMode = testNumber;
    135     rsgClearAllRenderTargets();
    136 }
    137 
    138 void setBenchmarkMode(int testNumber) {
    139     gIsDebugMode = false;
    140     if (testNumber == -1) {
    141         benchmarkSingleTest = false;
    142         benchMode = 0;
    143     } else {
    144         benchmarkSingleTest = true;
    145         benchMode = testNumber;
    146     }
    147 
    148     runningLoops = 0;
    149 }
    150 
    151 static void drawOffscreenResult(int posX, int posY, int width, int height) {
    152     bindProgramVertexOrtho();
    153 
    154     rs_matrix4x4 matrix;
    155     rsMatrixLoadIdentity(&matrix);
    156     rsgProgramVertexLoadModelMatrix(&matrix);
    157 
    158     rsgBindProgramFragment(gProgFragmentTexture);
    159 
    160     rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
    161     rsgBindTexture(gProgFragmentTexture, 0, gRenderBufferColor);
    162 
    163     float startX = posX, startY = posY;
    164     rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
    165                          startX, startY + height, 0, 0, 0,
    166                          startX + width, startY + height, 0, 1, 0,
    167                          startX + width, startY, 0, 1, 1);
    168 }
    169 
    170 static void benchmark() {
    171 
    172     gDt = 1.0f / 60.0f;
    173 
    174     rsgFinish();
    175     int64_t start = rsUptimeMillis();
    176 
    177     int drawPos = 0;
    178     int frameCount = 100;
    179     for(int i = 0; i < frameCount; i ++) {
    180         setupOffscreenTarget();
    181         gRenderSurfaceW = rsAllocationGetDimX(gRenderBufferColor);
    182         gRenderSurfaceH = rsAllocationGetDimY(gRenderBufferColor);
    183         rsgClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    184         rsgClearDepth(1.0f);
    185 
    186         runSubTest(benchMode);
    187         rsgClearAllRenderTargets();
    188         gRenderSurfaceW = rsgGetWidth();
    189         gRenderSurfaceH = rsgGetHeight();
    190         int size = 8;
    191         // draw each frame at (8, 3/4 gRenderSurfaceH) with size
    192         drawOffscreenResult((drawPos+=size)%gRenderSurfaceW, (gRenderSurfaceH * 3) / 4, size, size);
    193     }
    194 
    195     rsgFinish();
    196 
    197     int64_t end = rsUptimeMillis();
    198     float fps = (float)(frameCount) / ((float)(end - start)*0.001f);
    199     const char *testName = rsGetElementAt(gTestScripts[benchMode].debugName, 0);
    200     rsDebug(testName, fps);
    201 
    202     gResultBuffer[benchMode] = fps;
    203     int bufferW = rsAllocationGetDimX(gRenderBufferColor);
    204     int bufferH = rsAllocationGetDimY(gRenderBufferColor);
    205 
    206     int quadW = gRenderSurfaceW / 2;
    207     int quadH = (quadW * bufferH) / bufferW;
    208     drawOffscreenResult(0, 0, quadW, quadH);
    209 
    210     int left = 0, right = 0, top = 0, bottom = 0;
    211     uint height = rsgGetHeight();
    212     rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    213     rsgBindFont(gFontSerif);
    214     rsgMeasureText(gTestScripts[benchMode].testName, &left, &right, &top, &bottom);
    215     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
    216     rsgDrawText(gTestScripts[benchMode].testName, 2 -left, height - 2 + bottom);
    217 
    218     if (benchmarkSingleTest) {
    219         return;
    220     }
    221 
    222     benchMode ++;
    223     int testCount = rsAllocationGetDimX(rsGetAllocation(gTestScripts));
    224     if (benchMode == testCount) {
    225         rsSendToClientBlocking(RS_MSG_RESULTS_READY, gResultBuffer, testCount*sizeof(float));
    226         benchMode = 0;
    227         runningLoops++;
    228         if ((gMaxLoops > 0) && (runningLoops > gMaxLoops) && !sendMsgFlag) {
    229             //Notifiy the test to stop and get results
    230             rsDebug("gMaxLoops and runningLoops: ", gMaxLoops, runningLoops);
    231             rsSendToClientBlocking(RS_MSG_TEST_DONE);
    232             sendMsgFlag = true;
    233         }
    234     }
    235 }
    236 
    237 static void debug() {
    238     gDt = rsGetDt();
    239     runSubTest(benchMode);
    240 }
    241 
    242 int root(void) {
    243     gRenderSurfaceW = rsgGetWidth();
    244     gRenderSurfaceH = rsgGetHeight();
    245     rsgClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    246     rsgClearDepth(1.0f);
    247 
    248     if (!gLoadComplete) {
    249         rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
    250         rsgBindFont(gFontSerif);
    251         rsgDrawText("Loading", 50, 50);
    252         return 0;
    253     }
    254 
    255     if(!checkInit()) {
    256         return 1;
    257     }
    258 
    259     if (gPauseRendering) {
    260         rsgDrawText("Paused", 50, 50);
    261         return 30;
    262     }
    263     if (gIsDebugMode) {
    264         debug();
    265     } else {
    266         benchmark();
    267     }
    268 
    269     return 1;
    270 }
    271