1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.rs.sgtest; 18 19import android.app.Activity; 20import android.os.Bundle; 21import android.os.Handler; 22import android.os.Message; 23import android.graphics.BitmapFactory; 24import android.graphics.Bitmap; 25import android.graphics.Canvas; 26import android.view.SurfaceView; 27import android.widget.AdapterView; 28import android.widget.ArrayAdapter; 29import android.widget.ImageView; 30import android.widget.SeekBar; 31import android.widget.Spinner; 32import android.widget.TextView; 33import android.view.View; 34import android.util.Log; 35import android.renderscript.ScriptC; 36import android.renderscript.RenderScript; 37import android.renderscript.Type; 38import android.renderscript.Allocation; 39import android.renderscript.Element; 40import android.renderscript.Script; 41 42import android.os.Environment; 43import java.io.BufferedWriter; 44import java.io.File; 45import java.io.FileWriter; 46import java.io.IOException; 47import java.util.ArrayList; 48 49public class ScriptGroupTestActivity extends Activity 50 implements SeekBar.OnSeekBarChangeListener { 51 private final String TAG = "Img"; 52 public final String RESULT_FILE = "image_processing_result.csv"; 53 54 RenderScript mRS; 55 Allocation mInPixelsAllocation; 56 Allocation mOutPixelsAllocation; 57 58 Bitmap mBitmapOut; 59 60 private Spinner mSpinner; 61 62 private TextView mBenchmarkResult; 63 private Spinner mModeSpinner; 64 private Spinner mTestSpinner1; 65 private Spinner mTestSpinner2; 66 67 private ImageView mDisplayView; 68 69 private boolean mDoingBenchmark; 70 71 private TestBase mTest; 72 private int mRunCount; 73 74 public void updateDisplay() { 75 mHandler.sendMessage(Message.obtain()); 76 } 77 78 private Handler mHandler = new Handler() { 79 // Allow the filter to complete without blocking the UI 80 // thread. When the message arrives that the op is complete 81 // we will either mark completion or start a new filter if 82 // more work is ready. Either way, display the result. 83 @Override 84 public void handleMessage(Message msg) { 85 boolean doTest = false; 86 synchronized(this) { 87 if (mRS == null) { 88 return; 89 } 90 mTest.updateBitmap(mBitmapOut); 91 mDisplayView.invalidate(); 92 if (mRunCount > 0) { 93 mRunCount--; 94 if (mRunCount > 0) { 95 doTest = true; 96 } 97 } 98 99 if (doTest) { 100 mTest.runTestSendMessage(); 101 } 102 } 103 } 104 105 }; 106 107 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 108 } 109 110 public void onStartTrackingTouch(SeekBar seekBar) { 111 } 112 113 public void onStopTrackingTouch(SeekBar seekBar) { 114 } 115 116 void changeTest(int pos1, int pos2, int mode) { 117 if (mTest != null) { 118 mTest.destroy(); 119 } 120 121 final int[] index = new int[] { pos1, pos2 }; 122 mTest = new Filters(mode, index); 123 124 mTest.createBaseTest(this); 125 126 mTest.runTest(); 127 updateDisplay(); 128 mBenchmarkResult.setText("Result: not run"); 129 } 130 131 String getFilterName(int pos) { 132 return Filters.mFilterClasses[pos].getSimpleName(); 133 } 134 135 String[] getFilterNames() { 136 ArrayList<String> list = new ArrayList<String>(); 137 final int n = Filters.mFilterClasses.length; 138 for (int i = 0; i < n; i++) { 139 list.add(getFilterName(i)); 140 } 141 return list.toArray(new String[0]); 142 } 143 144 void setupTests() { 145 String[] names = getFilterNames(); 146 mModeSpinner.setAdapter(new ArrayAdapter<String>( 147 this, R.layout.spinner_layout, new String[] {"emulated", "native"})); 148 mTestSpinner1.setAdapter(new ArrayAdapter<String>( 149 this, R.layout.spinner_layout, names)); 150 mTestSpinner2.setAdapter(new ArrayAdapter<String>( 151 this, R.layout.spinner_layout, names)); 152 } 153 154 private AdapterView.OnItemSelectedListener mModeSpinnerListener = 155 new AdapterView.OnItemSelectedListener() { 156 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 157 changeTest( 158 mTestSpinner1.getSelectedItemPosition(), 159 mTestSpinner2.getSelectedItemPosition(), 160 pos); 161 } 162 163 public void onNothingSelected(AdapterView parent) { 164 } 165 }; 166 167 private AdapterView.OnItemSelectedListener mTestSpinner1Listener = 168 new AdapterView.OnItemSelectedListener() { 169 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 170 changeTest(pos, mTestSpinner2.getSelectedItemPosition(), 171 mModeSpinner.getSelectedItemPosition()); 172 } 173 174 public void onNothingSelected(AdapterView parent) { 175 } 176 }; 177 178 private AdapterView.OnItemSelectedListener mTestSpinner2Listener = 179 new AdapterView.OnItemSelectedListener() { 180 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 181 changeTest(mTestSpinner1.getSelectedItemPosition(), pos, 182 mModeSpinner.getSelectedItemPosition()); 183 } 184 185 public void onNothingSelected(AdapterView parent) { 186 } 187 }; 188 189 void init() { 190 mRS = RenderScript.create(this); 191 mInPixelsAllocation = Allocation.createFromBitmapResource( 192 mRS, getResources(), R.drawable.img1600x1067); 193 mBitmapOut = Bitmap.createBitmap(mInPixelsAllocation.getType().getX(), 194 mInPixelsAllocation.getType().getY(), 195 Bitmap.Config.ARGB_8888); 196 mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut); 197 198 mDisplayView = (ImageView) findViewById(R.id.display); 199 mDisplayView.setImageBitmap(mBitmapOut); 200 201 mModeSpinner = (Spinner) findViewById(R.id.modeselection); 202 mModeSpinner.setOnItemSelectedListener(mModeSpinnerListener); 203 mTestSpinner1 = (Spinner) findViewById(R.id.filterselection); 204 mTestSpinner1.setOnItemSelectedListener(mTestSpinner1Listener); 205 mTestSpinner2 = (Spinner) findViewById(R.id.filter2selection); 206 mTestSpinner2.setOnItemSelectedListener(mTestSpinner2Listener); 207 208 mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); 209 mBenchmarkResult.setText("Result: not run"); 210 211 setupTests(); 212 changeTest(0, 0, 0); 213 } 214 215 void cleanup() { 216 synchronized(this) { 217 RenderScript rs = mRS; 218 mRS = null; 219 while(mDoingBenchmark) { 220 try { 221 Thread.sleep(1, 0); 222 } catch(InterruptedException e) { 223 } 224 225 } 226 rs.destroy(); 227 } 228 229 mInPixelsAllocation = null; 230 mOutPixelsAllocation = null; 231 mBitmapOut = null; 232 } 233 234 @Override 235 protected void onCreate(Bundle savedInstanceState) { 236 super.onCreate(savedInstanceState); 237 setContentView(R.layout.main); 238 239 init(); 240 } 241 242 @Override 243 protected void onPause() { 244 super.onPause(); 245 246 cleanup(); 247 } 248 249 250 @Override 251 protected void onResume() { 252 super.onResume(); 253 254 if (null == mRS) { 255 init(); 256 } 257 } 258 259 // button hook 260 public void benchmark(View v) { 261 float t = getBenchmark(); 262 //long javaTime = javaFilter(); 263 //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); 264 mBenchmarkResult.setText("Result: " + t + " ms"); 265 Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t); 266 } 267 268 public void benchmark_all(View v) { 269 // write result into a file 270 File externalStorage = Environment.getExternalStorageDirectory(); 271 if (!externalStorage.canWrite()) { 272 Log.v(TAG, "sdcard is not writable"); 273 return; 274 } 275 File resultFile = new File(externalStorage, RESULT_FILE); 276 resultFile.setWritable(true, false); 277 try { 278 BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile)); 279 Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath()); 280 final int n = Filters.mFilterClasses.length; 281 for (int i = 0; i < n; i++) { 282 for (int j = 0; j < n; j++) { 283 for (int k = 0; k < 2; k++) { 284 changeTest(i, j, k); 285 float t = getBenchmark(); 286 String tn = getFilterName(i) + "-" + getFilterName(j); 287 if (k == 0) { 288 tn += " (emulated)"; 289 } else { 290 tn += " (native)"; 291 } 292 String s = new String("" + tn.toString() + ", " + t); 293 rsWriter.write(s + "\n"); 294 Log.v(TAG, "Test " + s + "ms\n"); 295 } 296 } 297 } 298 rsWriter.close(); 299 } catch (IOException e) { 300 Log.v(TAG, "Unable to write result file " + e.getMessage()); 301 } 302 changeTest(0, 0, 0); 303 Log.v(TAG, "result file:"+resultFile.getAbsolutePath()); 304 } 305 306 307 308 // For benchmark test 309 public float getBenchmark() { 310 if (mRS == null) { 311 return 0; 312 } 313 mDoingBenchmark = true; 314 315 mTest.setupBenchmark(); 316 long result = 0; 317 318 //Log.v(TAG, "Warming"); 319 long t = java.lang.System.currentTimeMillis() + 250; 320 do { 321 mTest.runTest(); 322 mTest.finish(); 323 } while (t > java.lang.System.currentTimeMillis()); 324 325 //Log.v(TAG, "Benchmarking"); 326 int ct = 0; 327 t = java.lang.System.currentTimeMillis(); 328 do { 329 mTest.runTest(); 330 mTest.finish(); 331 ct++; 332 } while ((t+1000) > java.lang.System.currentTimeMillis()); 333 t = java.lang.System.currentTimeMillis() - t; 334 float ft = (float)t; 335 ft /= ct; 336 337 mTest.exitBenchmark(); 338 mDoingBenchmark = false; 339 340 return ft; 341 } 342} 343