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