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