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.reference;
15 
16 import com.android.compatibility.common.util.WatchDog;
17 
18 import android.app.Activity;
19 import android.content.Intent;
20 import android.content.res.AssetManager;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.opengl.GLES20;
24 import android.opengl.GLUtils;
25 import android.opengl2.cts.GLActivityIntentKeys;
26 import android.os.Bundle;
27 import android.os.Handler;
28 import android.os.Message;
29 import android.view.Surface;
30 import android.view.SurfaceHolder;
31 import android.view.SurfaceView;
32 
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.util.concurrent.CountDownLatch;
36 
37 public class GLGameActivity extends Activity {
38 
39     public final static String SET_UP_TIME = "set_up_time";
40     public final static String UPDATE_TIMES = "update_times";
41     public final static String RENDER_TIMES = "render_times";
42 
43     private int mNumFrames;
44     private int mTimeout;
45     private double[] mSetUpTimes;
46     private double[] mUpdateTimes;
47     private double[] mRenderTimes;
48     private volatile Surface mSurface = null;
49     private CountDownLatch mStartSignal = new CountDownLatch(1);
50 
51     @Override
onCreate(Bundle data)52     public void onCreate(Bundle data) {
53         super.onCreate(data);
54         System.loadLibrary("ctsopengl_jni");
55 
56         Intent intent = getIntent();
57         mNumFrames = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_NUM_FRAMES, 1000);
58         mTimeout = intent.getIntExtra(GLActivityIntentKeys.INTENT_EXTRA_TIMEOUT, 1000000);
59 
60         SurfaceView surfaceView = new SurfaceView(this);
61         surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
62             @Override
63             public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
64                 mSurface = holder.getSurface();
65                 mStartSignal.countDown();
66             }
67 
68             @Override
69             public void surfaceCreated(SurfaceHolder holder) {}
70 
71             @Override
72             public void surfaceDestroyed(SurfaceHolder holder) {}
73         });
74         setContentView(surfaceView);
75 
76         // Spawns a worker.
77         Worker worker = new Worker(new Handler() {
78             @Override
79             public void handleMessage(Message msg) {
80                 Intent intent = new Intent();
81                 intent.putExtra(SET_UP_TIME, mSetUpTimes);
82                 intent.putExtra(UPDATE_TIMES, mUpdateTimes);
83                 intent.putExtra(RENDER_TIMES, mRenderTimes);
84                 setResult((msg.what == 1) ? RESULT_OK : RESULT_CANCELED, intent);
85                 finish();
86             }
87         });
88         worker.start();
89     }
90 
startBenchmark(AssetManager manager, Surface surface, int numFrames, double[] setUpTimes, double[] updateTimes, double[] renderTimes)91     private static native boolean startBenchmark(AssetManager manager,
92             Surface surface,
93             int numFrames,
94             double[] setUpTimes,
95             double[] updateTimes,
96             double[] renderTimes);
97 
98     /**
99      * This thread renderers the benchmarks, freeing the UI thread.
100      */
101     private class Worker extends Thread implements WatchDog.TimeoutCallback {
102 
103         private WatchDog watchDog;
104         private Handler mHandler;
105 
Worker(Handler handler)106         public Worker(Handler handler) {
107             mHandler = handler;
108         }
109 
110         @Override
run()111         public void run() {
112             try {
113                 mStartSignal.await();
114             } catch (InterruptedException e) {
115                 mHandler.sendEmptyMessage(0);
116                 return;
117             }
118             // Creates a watchdog to ensure a iteration doesn't exceed the timeout.
119             watchDog = new WatchDog(mTimeout, this);
120             watchDog.start();
121 
122             // Used to record the time taken to setup (GL, context, textures, meshes).
123             mSetUpTimes = new double[4];
124             // Used to record the times taken to update.
125             mUpdateTimes = new double[mNumFrames];
126             // Used to record the times taken to render.
127             mRenderTimes = new double[mNumFrames];
128             boolean success = startBenchmark(getAssets(),
129                     mSurface,
130                     mNumFrames,
131                     mSetUpTimes,
132                     mUpdateTimes,
133                     mRenderTimes);
134 
135             watchDog.stop();
136             mHandler.sendEmptyMessage((success) ? 1 : 0);
137         }
138 
139         @Override
onTimeout()140         public void onTimeout() {
141             mHandler.sendEmptyMessage(0);
142         }
143 
144     }
145 
loadTexture(AssetManager manager, String path)146     public static int loadTexture(AssetManager manager, String path) {
147         InputStream in = null;
148         try {
149             in = manager.open(path);
150         } catch (IOException e) {
151             e.printStackTrace();
152             return -1;
153         }
154         BitmapFactory.Options op = new BitmapFactory.Options();
155         op.inPreferredConfig = Bitmap.Config.ARGB_8888;
156         Bitmap bmp = BitmapFactory.decodeStream(in, null, op);
157         // generate textureID
158         int[] textures = new int[1];
159         GLES20.glGenTextures(1, textures, 0);
160         int textureID = textures[0];
161 
162         // create texture
163         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
164         GLES20.glTexParameteri(
165                 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
166         GLES20.glTexParameteri(
167                 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
168         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
169         GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
170         GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
171 
172         // clean up
173         try {
174             in.close();
175         } catch (IOException e) {
176             e.printStackTrace();
177         } finally {
178             bmp.recycle();
179         }
180         return textureID;
181     }
182 }
183