1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. 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 distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package android.opengl2.cts.primitive; 15 16 import com.android.compatibility.common.util.WatchDog; 17 18 import android.app.Activity; 19 import android.content.Intent; 20 import android.opengl2.cts.GLActivityIntentKeys; 21 import android.os.Bundle; 22 import android.util.Log; 23 import android.view.Surface; 24 import android.view.SurfaceHolder; 25 import android.view.SurfaceView; 26 27 import java.util.concurrent.CountDownLatch; 28 import java.util.concurrent.Semaphore; 29 30 public class GLPrimitiveActivity extends Activity { 31 32 public final static String TAG = "GLPrimitiveActivity"; 33 34 private volatile Exception mException; 35 private volatile Surface mSurface = null; 36 private CountDownLatch mStartSignal = new CountDownLatch(1); 37 private Semaphore mSemaphore = new Semaphore(0); 38 39 private BenchmarkName mBenchmark; 40 private boolean mOffscreen; 41 private int mNumFrames; 42 private int mNumIterations; 43 private int mTimeout; 44 public double[] mFpsValues; 45 46 @Override onCreate(Bundle data)47 public void onCreate(Bundle data) { 48 super.onCreate(data); 49 System.loadLibrary("ctsopengl_jni"); 50 Intent intent = getIntent(); 51 mBenchmark = BenchmarkName.valueOf( 52 intent.getStringExtra(GLActivityIntentKeys.INTENT_EXTRA_BENCHMARK_NAME)); 53 mOffscreen = intent.getBooleanExtra(GLActivityIntentKeys.INTENT_EXTRA_OFFSCREEN, false); 54 mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 0); 55 mNumIterations = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_ITERATIONS, 0); 56 mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 0); 57 mFpsValues = new double[mNumIterations]; 58 59 Log.i(TAG, "Benchmark: " + mBenchmark); 60 Log.i(TAG, "Offscreen: " + mOffscreen); 61 Log.i(TAG, "Num Frames: " + mNumFrames); 62 Log.i(TAG, "Num Iterations: " + mNumIterations); 63 Log.i(TAG, "Time Out: " + mTimeout); 64 65 SurfaceView surfaceView = new SurfaceView(this); 66 surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() { 67 @Override 68 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 69 mSurface = holder.getSurface(); 70 mStartSignal.countDown(); 71 } 72 73 @Override 74 public void surfaceCreated(SurfaceHolder holder) {} 75 76 @Override 77 public void surfaceDestroyed(SurfaceHolder holder) {} 78 }); 79 setContentView(surfaceView); 80 // Spawns a worker to run the benchmark. 81 Worker worker = new Worker(); 82 worker.start(); 83 } 84 waitForCompletion()85 public void waitForCompletion() throws Exception { 86 // Wait for semiphore. 87 mSemaphore.acquire(); 88 if (mException != null) { 89 throw mException; 90 } 91 } 92 complete()93 private void complete() { 94 // Release semiphore. 95 mSemaphore.release(); 96 finish(); 97 } 98 setException(Exception e)99 private synchronized void setException(Exception e) { 100 if (mException == null) { 101 mException = e; 102 } 103 } 104 setupBenchmark( Surface surface, int benchmark, boolean offscreen)105 private static native boolean setupBenchmark( 106 Surface surface, int benchmark, boolean offscreen); 107 startBenchmark(int workload, int numFrames, double[] frameTimes)108 private static native boolean startBenchmark(int workload, int numFrames, double[] frameTimes); 109 tearDownBenchmark()110 private static native void tearDownBenchmark(); 111 112 /** 113 * This thread runs the benchmarks, freeing the UI thread. 114 */ 115 private class Worker extends Thread implements WatchDog.TimeoutCallback { 116 117 private WatchDog watchDog; 118 private volatile boolean success = true; 119 120 @Override run()121 public void run() { 122 try { 123 mStartSignal.await(); 124 } catch (InterruptedException e) { 125 setException(e); 126 complete(); 127 return; 128 } 129 Log.i(TAG, mBenchmark + " Benchmark Started"); 130 // Creates a watchdog to ensure a iteration doesn't exceed the timeout. 131 watchDog = new WatchDog(mTimeout, this); 132 // Used to record the start and end time of the iteration. 133 double[] times = new double[2]; 134 try { 135 // Setup the benchmark. 136 setupBenchmark(mSurface, mBenchmark.ordinal(), mOffscreen); 137 for (int i = 0; i < mNumIterations && success; i++) { 138 // The workload to use for this iteration. 139 int workload = i + 1; 140 watchDog.start(); 141 // Start benchmark. 142 success = startBenchmark(workload, mNumFrames, times); 143 watchDog.stop(); 144 if (!success) { 145 setException(new Exception("Benchmark failed to run")); 146 } else { 147 // Calculate FPS. 148 mFpsValues[i] = mNumFrames * 1000.0f / (times[1] - times[0]); 149 } 150 } 151 } 152 finally 153 { 154 tearDownBenchmark(); 155 } 156 157 complete(); 158 Log.i(TAG, mBenchmark + " Benchmark Completed"); 159 } 160 onTimeout()161 public void onTimeout() { 162 setException(new Exception("Benchmark timed out")); 163 complete(); 164 } 165 166 } 167 } 168