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 GlVboPerfTest()37 public GlVboPerfTest() { 38 super(GlPlanetsActivity.class); 39 } 40 testVboWithVaryingIndexBufferNumbers()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 testVboVsNonVboPerfGeometry0()81 public void testVboVsNonVboPerfGeometry0() throws Exception { 82 doRunVboVsNonVboPerfTest(0); 83 } 84 testVboVsNonVboPerfGeometry1()85 public void testVboVsNonVboPerfGeometry1() throws Exception { 86 doRunVboVsNonVboPerfTest(4); 87 } 88 runRendering(int numPlanets, boolean useVboVertex, boolean useVboIndex, int numIndexBuffers)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 cleanUpActivity()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 doRunVboVsNonVboPerfTest(int numPlanets)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 findMinMax(float[] data)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