ImageProcessingActivityJB.java revision 31f4588d26e258c61543e90e796c4c9a8c2a1482
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.imagejb; 18 19import android.app.Activity; 20import android.content.Intent; 21import android.os.Bundle; 22import android.os.Handler; 23import android.os.Message; 24import android.graphics.BitmapFactory; 25import android.graphics.Bitmap; 26import android.graphics.Canvas; 27import android.view.SurfaceView; 28import android.widget.AdapterView; 29import android.widget.ArrayAdapter; 30import android.widget.ImageView; 31import android.widget.SeekBar; 32import android.widget.Spinner; 33import android.widget.TextView; 34import android.view.View; 35import android.view.TextureView; 36import android.view.Surface; 37import android.graphics.SurfaceTexture; 38import android.util.Log; 39import android.renderscript.ScriptC; 40import android.renderscript.RenderScript; 41import android.renderscript.Type; 42import android.renderscript.Allocation; 43import android.renderscript.Element; 44import android.renderscript.Script; 45 46import android.os.Environment; 47import java.io.BufferedWriter; 48import java.io.File; 49import java.io.FileWriter; 50import java.io.IOException; 51 52public class ImageProcessingActivityJB extends Activity 53 implements SeekBar.OnSeekBarChangeListener, 54 TextureView.SurfaceTextureListener { 55 private final String TAG = "Img"; 56 public final String RESULT_FILE = "image_processing_result.csv"; 57 58 Bitmap mBitmapIn; 59 Bitmap mBitmapIn2; 60 61 private Spinner mSpinner; 62 private SeekBar mBar1; 63 private SeekBar mBar2; 64 private SeekBar mBar3; 65 private SeekBar mBar4; 66 private SeekBar mBar5; 67 private TextView mText1; 68 private TextView mText2; 69 private TextView mText3; 70 private TextView mText4; 71 private TextView mText5; 72 private TextureView mDisplayView; 73 74 private int mTestList[]; 75 private float mTestResults[]; 76 77 private boolean mToggleIO; 78 private boolean mToggleDVFS; 79 private boolean mToggleLong; 80 private boolean mTogglePause; 81 82 83 ///////////////////////////////////////////////////////////////////////// 84 85 class Processor extends Thread { 86 RenderScript mRS; 87 Allocation mInPixelsAllocation; 88 Allocation mInPixelsAllocation2; 89 Allocation mOutDisplayAllocation; 90 Allocation mOutPixelsAllocation; 91 92 private Surface mOutSurface; 93 private float mLastResult; 94 private boolean mRun = true; 95 private int mOp = 0; 96 private boolean mDoingBenchmark; 97 private TestBase mTest; 98 private TextureView mDisplayView; 99 100 private boolean mBenchmarkMode; 101 102 103 Processor(RenderScript rs, TextureView v, boolean benchmarkMode) { 104 mRS = rs; 105 mDisplayView = v; 106 mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn); 107 mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, mBitmapIn2); 108 mOutDisplayAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(), 109 Allocation.MipmapControl.MIPMAP_NONE, 110 Allocation.USAGE_SCRIPT | 111 Allocation.USAGE_IO_OUTPUT); 112 mOutPixelsAllocation = mOutDisplayAllocation; 113 114 if (!mToggleIO) { 115 // Not using USAGE_IO for the script so create a non-io kernel to copy from 116 mOutPixelsAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(), 117 Allocation.MipmapControl.MIPMAP_NONE, 118 Allocation.USAGE_SCRIPT); 119 } 120 121 mBenchmarkMode = benchmarkMode; 122 start(); 123 } 124 125 private float getBenchmark() { 126 mDoingBenchmark = true; 127 128 mTest.setupBenchmark(); 129 long result = 0; 130 long runtime = 1000; 131 if (mToggleLong) { 132 runtime = 10000; 133 } 134 135 if (mToggleDVFS) { 136 mDvfsWar.go(); 137 } 138 139 Log.v("rs", "Warming"); 140 long t = java.lang.System.currentTimeMillis() + 250; 141 do { 142 mTest.runTest(); 143 mTest.finish(); 144 } while (t > java.lang.System.currentTimeMillis()); 145 //mHandler.sendMessage(Message.obtain()); 146 147 Log.v("rs", "Benchmarking"); 148 int ct = 0; 149 t = java.lang.System.currentTimeMillis(); 150 do { 151 mTest.runTest(); 152 mTest.finish(); 153 ct++; 154 } while ((t + runtime) > java.lang.System.currentTimeMillis()); 155 t = java.lang.System.currentTimeMillis() - t; 156 float ft = (float)t; 157 ft /= ct; 158 159 mTest.exitBenchmark(); 160 mDoingBenchmark = false; 161 162 android.util.Log.v("rs", "bench " + ft); 163 return ft; 164 } 165 166 private Handler mHandler = new Handler() { 167 // Allow the filter to complete without blocking the UI 168 // thread. When the message arrives that the op is complete 169 // we will either mark completion or start a new filter if 170 // more work is ready. Either way, display the result. 171 @Override 172 public void handleMessage(Message msg) { 173 synchronized(this) { 174 if (mRS == null || mOutPixelsAllocation == null) { 175 return; 176 } 177 if (mOutDisplayAllocation != mOutPixelsAllocation) { 178 mOutDisplayAllocation.copyFrom(mOutPixelsAllocation); 179 } 180 mOutDisplayAllocation.ioSend(); 181 mDisplayView.invalidate(); 182 //mTest.runTestSendMessage(); 183 } 184 } 185 }; 186 187 public void run() { 188 Surface lastSurface = null; 189 while (mRun) { 190 synchronized(this) { 191 try { 192 this.wait(); 193 } catch(InterruptedException e) { 194 } 195 if (!mRun) return; 196 197 if ((mOutSurface == null) || (mOutPixelsAllocation == null)) { 198 continue; 199 } 200 201 if (lastSurface != mOutSurface) { 202 mOutDisplayAllocation.setSurface(mOutSurface); 203 lastSurface = mOutSurface; 204 } 205 } 206 207 if (mBenchmarkMode) { 208 for (int ct=0; ct < mTestList.length; ct++) { 209 mRS.finish(); 210 211 try { 212 sleep(1000); 213 } catch(InterruptedException e) { 214 } 215 216 if (mTest != null) { 217 mTest.destroy(); 218 } 219 220 mTest = changeTest(mTestList[ct]); 221 if (mTogglePause) { 222 try { 223 sleep(10000); 224 } catch(InterruptedException e) { 225 } 226 } 227 228 mTestResults[ct] = getBenchmark(); 229 mHandler.sendMessage(Message.obtain()); 230 } 231 onBenchmarkFinish(); 232 } 233 } 234 235 } 236 237 public void update() { 238 synchronized(this) { 239 if (mOp == 0) { 240 mOp = 2; 241 } 242 notifyAll(); 243 } 244 } 245 246 public void setSurface(Surface s) { 247 synchronized(this) { 248 mOutSurface = s; 249 notifyAll(); 250 } 251 //update(); 252 } 253 254 public void exit() { 255 mRun = false; 256 257 synchronized(this) { 258 notifyAll(); 259 } 260 261 try { 262 this.join(); 263 } catch(InterruptedException e) { 264 } 265 266 mInPixelsAllocation.destroy(); 267 mInPixelsAllocation2.destroy(); 268 if (mOutPixelsAllocation != mOutDisplayAllocation) { 269 mOutPixelsAllocation.destroy(); 270 } 271 mOutDisplayAllocation.destroy(); 272 mRS.destroy(); 273 274 mInPixelsAllocation = null; 275 mInPixelsAllocation2 = null; 276 mOutPixelsAllocation = null; 277 mOutDisplayAllocation = null; 278 mRS = null; 279 } 280 } 281 282 /////////////////////////////////////////////////////////////////////////////////////// 283 284 static class DVFSWorkaround { 285 static class spinner extends Thread { 286 boolean mRun = true; 287 long mNextSleep; 288 289 spinner() { 290 setPriority(MIN_PRIORITY); 291 start(); 292 } 293 294 public void run() { 295 while (mRun) { 296 Thread.yield(); 297 synchronized(this) { 298 long t = java.lang.System.currentTimeMillis(); 299 if (t > mNextSleep) { 300 try { 301 this.wait(); 302 } catch(InterruptedException e) { 303 } 304 } 305 } 306 } 307 } 308 309 public void go(long t) { 310 synchronized(this) { 311 mNextSleep = t; 312 notifyAll(); 313 } 314 } 315 } 316 317 spinner s1; 318 DVFSWorkaround() { 319 s1 = new spinner(); 320 } 321 322 void go() { 323 long t = java.lang.System.currentTimeMillis() + 2000; 324 s1.go(t); 325 } 326 327 void destroy() { 328 synchronized(this) { 329 s1.mRun = false; 330 notifyAll(); 331 } 332 } 333 } 334 DVFSWorkaround mDvfsWar = new DVFSWorkaround(); 335 336 /////////////////////////////////////////////////////////// 337 338 339 private boolean mDoingBenchmark; 340 public Processor mProcessor; 341 342 343 private Handler mHandler = new Handler() { 344 @Override 345 public void handleMessage(Message msg) { 346 mDisplayView.invalidate(); 347 } 348 }; 349 350 public void updateDisplay() { 351 mHandler.sendMessage(Message.obtain()); 352 //mProcessor.update(); 353 } 354 355 TestBase changeTest(int id) { 356 IPTestListJB.TestName t = IPTestListJB.TestName.values()[id]; 357 TestBase tb = IPTestListJB.newTest(t); 358 tb.createBaseTest(this); 359 //setupBars(tb); 360 return tb; 361 } 362 363 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 364 if (fromUser) { 365 if (seekBar == mBar1) { 366 mProcessor.mTest.onBar1Changed(progress); 367 } else if (seekBar == mBar2) { 368 mProcessor.mTest.onBar2Changed(progress); 369 } else if (seekBar == mBar3) { 370 mProcessor.mTest.onBar3Changed(progress); 371 } else if (seekBar == mBar4) { 372 mProcessor.mTest.onBar4Changed(progress); 373 } else if (seekBar == mBar5) { 374 mProcessor.mTest.onBar5Changed(progress); 375 } 376 mProcessor.update(); 377 } 378 } 379 380 public void onStartTrackingTouch(SeekBar seekBar) { 381 } 382 383 public void onStopTrackingTouch(SeekBar seekBar) { 384 } 385 386 void setupBars(TestBase t) { 387 mSpinner.setVisibility(View.VISIBLE); 388 t.onSpinner1Setup(mSpinner); 389 390 mBar1.setVisibility(View.VISIBLE); 391 mText1.setVisibility(View.VISIBLE); 392 t.onBar1Setup(mBar1, mText1); 393 394 mBar2.setVisibility(View.VISIBLE); 395 mText2.setVisibility(View.VISIBLE); 396 t.onBar2Setup(mBar2, mText2); 397 398 mBar3.setVisibility(View.VISIBLE); 399 mText3.setVisibility(View.VISIBLE); 400 t.onBar3Setup(mBar3, mText3); 401 402 mBar4.setVisibility(View.VISIBLE); 403 mText4.setVisibility(View.VISIBLE); 404 t.onBar4Setup(mBar4, mText4); 405 406 mBar5.setVisibility(View.VISIBLE); 407 mText5.setVisibility(View.VISIBLE); 408 t.onBar5Setup(mBar5, mText5); 409 } 410 411 412 void cleanup() { 413 synchronized(this) { 414 mProcessor.exit(); 415 } 416 417 mBitmapIn = null; 418 mBitmapIn2 = null; 419 } 420 421 @Override 422 protected void onCreate(Bundle savedInstanceState) { 423 super.onCreate(savedInstanceState); 424 setContentView(R.layout.main); 425 426 mBitmapIn = loadBitmap(R.drawable.img1600x1067); 427 mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b); 428 429 mDisplayView = (TextureView) findViewById(R.id.display); 430 431 mSpinner = (Spinner) findViewById(R.id.spinner1); 432 433 mBar1 = (SeekBar) findViewById(R.id.slider1); 434 mBar2 = (SeekBar) findViewById(R.id.slider2); 435 mBar3 = (SeekBar) findViewById(R.id.slider3); 436 mBar4 = (SeekBar) findViewById(R.id.slider4); 437 mBar5 = (SeekBar) findViewById(R.id.slider5); 438 439 mBar1.setOnSeekBarChangeListener(this); 440 mBar2.setOnSeekBarChangeListener(this); 441 mBar3.setOnSeekBarChangeListener(this); 442 mBar4.setOnSeekBarChangeListener(this); 443 mBar5.setOnSeekBarChangeListener(this); 444 445 mText1 = (TextView) findViewById(R.id.slider1Text); 446 mText2 = (TextView) findViewById(R.id.slider2Text); 447 mText3 = (TextView) findViewById(R.id.slider3Text); 448 mText4 = (TextView) findViewById(R.id.slider4Text); 449 mText5 = (TextView) findViewById(R.id.slider5Text); 450 } 451 452 @Override 453 protected void onPause() { 454 super.onPause(); 455 456 cleanup(); 457 } 458 459 public void onBenchmarkFinish() { 460 Intent intent = new Intent(); 461 intent.putExtra("tests", mTestList); 462 intent.putExtra("results", mTestResults); 463 setResult(RESULT_OK, intent); 464 finish(); 465 } 466 467 @Override 468 protected void onResume() { 469 super.onResume(); 470 Intent i = getIntent(); 471 mTestList = i.getIntArrayExtra("tests"); 472 473 mToggleIO = i.getBooleanExtra("enable io", true); 474 mToggleDVFS = i.getBooleanExtra("enable dvfs", true); 475 mToggleLong = i.getBooleanExtra("enable long", false); 476 mTogglePause = i.getBooleanExtra("enable pause", false); 477 478 mTestResults = new float[mTestList.length]; 479 480 mProcessor = new Processor(RenderScript.create(this), mDisplayView, true); 481 mDisplayView.setSurfaceTextureListener(this); 482 } 483 484 protected void onDestroy() { 485 super.onDestroy(); 486 } 487 488 private Bitmap loadBitmap(int resource) { 489 final BitmapFactory.Options options = new BitmapFactory.Options(); 490 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 491 return BitmapFactory.decodeResource(getResources(), resource, options); 492 } 493 494 495 496 @Override 497 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 498 mProcessor.setSurface(new Surface(surface)); 499 } 500 501 @Override 502 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 503 mProcessor.setSurface(new Surface(surface)); 504 } 505 506 @Override 507 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 508 mProcessor.setSurface(null); 509 return true; 510 } 511 512 @Override 513 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 514 } 515} 516