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 com.android.cts.opengl.reference; 15 16 import com.android.cts.opengl.GLActivityIntentKeys; 17 18 import android.app.Activity; 19 import android.content.Intent; 20 import android.content.res.AssetManager; 21 import android.cts.util.WatchDog; 22 import android.graphics.Bitmap; 23 import android.graphics.BitmapFactory; 24 import android.opengl.GLES20; 25 import android.opengl.GLUtils; 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 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 onTimeout()138 public void onTimeout() { 139 mHandler.sendEmptyMessage(0); 140 } 141 142 } 143 loadTexture(AssetManager manager, String path)144 public static int loadTexture(AssetManager manager, String path) { 145 InputStream in = null; 146 try { 147 in = manager.open(path); 148 } catch (IOException e) { 149 e.printStackTrace(); 150 return -1; 151 } 152 BitmapFactory.Options op = new BitmapFactory.Options(); 153 op.inPreferredConfig = Bitmap.Config.ARGB_8888; 154 Bitmap bmp = BitmapFactory.decodeStream(in, null, op); 155 // generate textureID 156 int[] textures = new int[1]; 157 GLES20.glGenTextures(1, textures, 0); 158 int textureID = textures[0]; 159 160 // create texture 161 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID); 162 GLES20.glTexParameteri( 163 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 164 GLES20.glTexParameteri( 165 GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 166 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 167 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 168 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0); 169 170 // clean up 171 try { 172 in.close(); 173 } catch (IOException e) { 174 e.printStackTrace(); 175 } finally { 176 bmp.recycle(); 177 } 178 return textureID; 179 } 180 } 181