Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 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 android.openglperf.cts;
     18 
     19 import android.app.Instrumentation;
     20 import android.content.Intent;
     21 import android.test.ActivityInstrumentationTestCase2;
     22 import android.util.Log;
     23 
     24 public class GlVboPerfTest extends
     25         ActivityInstrumentationTestCase2<GlPlanetsActivity> {
     26     private static final String TAG = "GlVboPerfTest";
     27     private static final int NUM_FRAMES_TO_RENDER = 100;
     28     private static final long RENDERING_TIMEOUT = 5 * 60;
     29     // 30% of fps_no_vbo is allowed to compensate variations in measurement
     30     private static final float FPS_COMPARISON_MARGIN = 0.3f;
     31     // the worst case should be above 70% of the best case
     32     private static final float FPS_MIN_MAX_COMPARISON_PERCENTILE = 0.7f;
     33 
     34     private float mFps;
     35     private int mNumTriangles;
     36 
     37     public GlVboPerfTest() {
     38         super(GlPlanetsActivity.class);
     39     }
     40 
     41     public void testVboWithVaryingIndexBufferNumbers() throws Exception {
     42         final int[] numIndexBuffers = {1, 10, 100, 200, 400}; // per vertex buffer
     43         float[] fpsVbo = new float[numIndexBuffers.length];
     44         float[] fpsNonVbo = new float[numIndexBuffers.length];
     45 
     46         for (int i = 0; i < numIndexBuffers.length; i++) {
     47             runRendering(0, true, true, numIndexBuffers[i]);
     48             fpsVbo[i] = mFps;
     49             runRendering(0, true, false, numIndexBuffers[i]);
     50             fpsNonVbo[i] = mFps;
     51         }
     52         StringBuilder msgIndex = new StringBuilder();
     53         StringBuilder msgVbo = new StringBuilder();
     54         StringBuilder msgNonVbo = new StringBuilder();
     55         msgIndex.append("index buffer ");
     56         msgVbo.append("Vbo ");
     57         msgNonVbo.append("Non-Vbo ");
     58         for (int i = 0; i < numIndexBuffers.length; i++) {
     59             msgIndex.append(numIndexBuffers[i]).append(" ");
     60             msgVbo.append(fpsVbo[i]).append(" ");
     61             msgNonVbo.append(fpsNonVbo[i]).append(" ");
     62         }
     63         Log.i(TAG, msgIndex.toString());
     64         Log.i(TAG, msgVbo.toString());
     65         Log.i(TAG, msgNonVbo.toString());
     66 
     67         float[] minMaxVbo = findMinMax(fpsVbo);
     68         float[] minMaxNonVbo = findMinMax(fpsNonVbo);
     69 
     70         float delta = minMaxVbo[1] - (1f - FPS_COMPARISON_MARGIN)
     71                 * minMaxNonVbo[1];
     72         assertTrue("VBO performance worse than non-VBO " + msgVbo + msgNonVbo, delta > 0f);
     73         assertTrue(
     74                 "Too much FPS drop for VBO case " + msgVbo,
     75                 minMaxVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxVbo[1]));
     76         assertTrue(
     77                 "Too much FPS drop for No VBO case " + msgNonVbo,
     78                 minMaxNonVbo[0] > (FPS_MIN_MAX_COMPARISON_PERCENTILE * minMaxNonVbo[1]));
     79     }
     80 
     81     public void testVboVsNonVboPerfGeometry0() throws Exception {
     82         doRunVboVsNonVboPerfTest(0);
     83     }
     84 
     85     public void testVboVsNonVboPerfGeometry1() throws Exception {
     86         doRunVboVsNonVboPerfTest(4);
     87     }
     88 
     89     private void runRendering(int numPlanets, boolean useVboVertex, boolean useVboIndex,
     90             int numIndexBuffers) throws Exception {
     91         Intent intent = new Intent();
     92         intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_FRAMES,
     93                 NUM_FRAMES_TO_RENDER);
     94         intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_PLANETS, numPlanets);
     95         intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_VERTICES, useVboVertex);
     96         intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_USE_VBO_INDICES, useVboIndex);
     97         intent.putExtra(GlPlanetsActivity.INTENT_EXTRA_NUM_INDEX_BUFFERS, numIndexBuffers);
     98 
     99         setActivityIntent(intent);
    100         final GlPlanetsActivity activity = getActivity();
    101         boolean waitResult = activity
    102                 .waitForGlPlanetsCompletionWithTimeout(RENDERING_TIMEOUT);
    103         assertTrue("timeout while waiting for rendering completion", waitResult);
    104 
    105         mFps = activity.getAverageFps();
    106         mNumTriangles = activity.getNumTriangles();
    107 
    108         cleanUpActivity();
    109     }
    110 
    111     private void cleanUpActivity()  throws Exception {
    112         // finish the current activity and do clean-up so that a new activity
    113         // can be launched in the same test run
    114         super.tearDown();
    115         super.setUp();
    116         // wait until clean-up / set-up finishes
    117         getInstrumentation().waitForIdleSync();
    118     }
    119 
    120     private void doRunVboVsNonVboPerfTest(int numPlanets) throws Exception {
    121         runRendering(numPlanets, true, true, 1); // VBO
    122         int numTrianglesVbo = mNumTriangles;
    123         float fpsVbo = mFps;
    124         runRendering(numPlanets, false, false, 1); // non-VBO
    125 
    126         assertTrue("Number of triangles mismatch",
    127                 numTrianglesVbo == mNumTriangles);
    128 
    129         // Margin amount of error is allowed due to measuring irregularity
    130         float delta = fpsVbo - (1f - FPS_COMPARISON_MARGIN) * mFps;
    131         StringBuilder testMsg = new StringBuilder();
    132         testMsg.append("VBO performance worse than non-VBO ").append(fpsVbo).append(" ");
    133         testMsg.append(mFps);
    134         assertTrue(testMsg.toString(), delta > 0f);
    135     }
    136 
    137     private float[] findMinMax(float[] data) {
    138         float min = data[0];
    139         float max = data[0];
    140 
    141         for (int i = 1; i < data.length; i++) {
    142             if (data[i] > max) max = data[i];
    143             if (data[i] < min) min = data[i];
    144         }
    145         float[] result = {min, max};
    146         return result;
    147     }
    148 }
    149