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