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.image2; 18 19import android.app.Activity; 20import android.os.Bundle; 21import android.graphics.BitmapFactory; 22import android.graphics.Bitmap; 23import android.graphics.Canvas; 24import android.support.v8.renderscript.*; 25import android.view.SurfaceView; 26import android.view.SurfaceHolder; 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 java.lang.Math; 36 37import android.os.Environment; 38import android.app.Instrumentation; 39import android.content.Context; 40import android.content.Intent; 41import android.net.Uri; 42import java.io.BufferedWriter; 43import java.io.File; 44import java.io.FileWriter; 45import java.io.IOException; 46 47public class ImageProcessingActivity2 extends Activity 48 implements SeekBar.OnSeekBarChangeListener { 49 private final String TAG = "Img"; 50 public final String RESULT_FILE = "image_processing_result.csv"; 51 52 RenderScript mRS; 53 Allocation mInPixelsAllocation; 54 Allocation mInPixelsAllocation2; 55 Allocation mOutPixelsAllocation; 56 57 /** 58 * Define enum type for test names 59 */ 60 public enum TestName { 61 // totally there are 38 test cases 62 LEVELS_VEC3_RELAXED ("Levels Vec3 Relaxed"), 63 LEVELS_VEC4_RELAXED ("Levels Vec4 Relaxed"), 64 LEVELS_VEC3_FULL ("Levels Vec3 Full"), 65 LEVELS_VEC4_FULL ("Levels Vec4 Full"), 66 BLUR_RADIUS_25 ("Blur radius 25"), 67 INTRINSIC_BLUE_RADIUS_25 ("Intrinsic Blur radius 25"), 68 GREYSCALE ("Greyscale"), 69 GRAIN ("Grain"), 70 FISHEYE_FULL ("Fisheye Full"), 71 FISHEYE_RELAXED ("Fisheye Relaxed"), 72 FISHEYE_APPROXIMATE_FULL ("Fisheye Approximate Full"), 73 FISHEYE_APPROXIMATE_RELAXED ("Fisheye Approximate Relaxed"), 74 VIGNETTE_FULL ("Vignette Full"), 75 VIGNETTE_RELAXED ("Vignette Relaxed"), 76 VIGNETTE_APPROXIMATE_FULL ("Vignette Approximate Full"), 77 VIGNETTE_APPROXIMATE_RELAXED ("Vignette Approximate Relaxed"), 78 GROUP_TEST_EMULATED ("Group Test (emulated)"), 79 GROUP_TEST_NATIVE ("Group Test (native)"), 80 CONVOLVE_3X3 ("Convolve 3x3"), 81 INTRINSICS_CONVOLVE_3X3 ("Intrinsics Convolve 3x3"), 82 COLOR_MATRIX ("ColorMatrix"), 83 INTRINSICS_COLOR_MATRIX ("Intrinsics ColorMatrix"), 84 INTRINSICS_COLOR_MATRIX_GREY ("Intrinsics ColorMatrix Grey"), 85 COPY ("Copy"), 86 CROSS_PROCESS_USING_LUT ("CrossProcess (using LUT)"), 87 CONVOLVE_5X5 ("Convolve 5x5"), 88 INTRINSICS_CONVOLVE_5X5 ("Intrinsics Convolve 5x5"), 89 MANDELBROT ("Mandelbrot"), 90 INTRINSICS_BLEND ("Intrinsics Blend"), 91 INTRINSICS_BLUR_25G ("Intrinsics Blur 25 uchar"), 92 VIBRANCE ("Vibrance"), 93 BW_FILTER ("BW Filter"), 94 SHADOWS ("Shadows"), 95 CONTRAST ("Contrast"), 96 EXPOSURE ("Exposure"), 97 WHITE_BALANCE ("White Balance"), 98 COLOR_CUBE ("Color Cube"), 99 COLOR_CUBE_3D_INTRINSIC ("Color Cube (3D LUT intrinsic)"); 100 101 102 private final String name; 103 104 private TestName(String s) { 105 name = s; 106 } 107 108 // return quoted string as displayed test name 109 public String toString() { 110 return name; 111 } 112 } 113 114 Bitmap mBitmapIn; 115 Bitmap mBitmapIn2; 116 Bitmap mBitmapOut; 117 118 private Spinner mSpinner; 119 private SeekBar mBar1; 120 private SeekBar mBar2; 121 private SeekBar mBar3; 122 private SeekBar mBar4; 123 private SeekBar mBar5; 124 private TextView mText1; 125 private TextView mText2; 126 private TextView mText3; 127 private TextView mText4; 128 private TextView mText5; 129 130 private float mSaturation = 1.0f; 131 132 private TextView mBenchmarkResult; 133 private Spinner mTestSpinner; 134 135 private SurfaceView mSurfaceView; 136 private ImageView mDisplayView; 137 138 private boolean mDoingBenchmark; 139 140 private TestBase mTest; 141 private int mRunCount; 142 143 public void updateDisplay() { 144 mTest.updateBitmap(mBitmapOut); 145 mDisplayView.invalidate(); 146 } 147 148 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 149 if (fromUser) { 150 151 if (seekBar == mBar1) { 152 mTest.onBar1Changed(progress); 153 } else if (seekBar == mBar2) { 154 mTest.onBar2Changed(progress); 155 } else if (seekBar == mBar3) { 156 mTest.onBar3Changed(progress); 157 } else if (seekBar == mBar4) { 158 mTest.onBar4Changed(progress); 159 } else if (seekBar == mBar5) { 160 mTest.onBar5Changed(progress); 161 } 162 163 mTest.runTest(); 164 updateDisplay(); 165 } 166 } 167 168 public void onStartTrackingTouch(SeekBar seekBar) { 169 } 170 171 public void onStopTrackingTouch(SeekBar seekBar) { 172 } 173 174 void setupBars() { 175 mSpinner.setVisibility(View.VISIBLE); 176 mTest.onSpinner1Setup(mSpinner); 177 178 mBar1.setVisibility(View.VISIBLE); 179 mText1.setVisibility(View.VISIBLE); 180 mTest.onBar1Setup(mBar1, mText1); 181 182 mBar2.setVisibility(View.VISIBLE); 183 mText2.setVisibility(View.VISIBLE); 184 mTest.onBar2Setup(mBar2, mText2); 185 186 mBar3.setVisibility(View.VISIBLE); 187 mText3.setVisibility(View.VISIBLE); 188 mTest.onBar3Setup(mBar3, mText3); 189 190 mBar4.setVisibility(View.VISIBLE); 191 mText4.setVisibility(View.VISIBLE); 192 mTest.onBar4Setup(mBar4, mText4); 193 194 mBar5.setVisibility(View.VISIBLE); 195 mText5.setVisibility(View.VISIBLE); 196 mTest.onBar5Setup(mBar5, mText5); 197 } 198 199 200 void changeTest(TestName testName) { 201 if (mTest != null) { 202 mTest.destroy(); 203 } 204 switch(testName) { 205 case LEVELS_VEC3_RELAXED: 206 mTest = new LevelsV4(false, false); 207 break; 208 case LEVELS_VEC4_RELAXED: 209 mTest = new LevelsV4(false, true); 210 break; 211 case LEVELS_VEC3_FULL: 212 mTest = new LevelsV4(true, false); 213 break; 214 case LEVELS_VEC4_FULL: 215 mTest = new LevelsV4(true, true); 216 break; 217 case BLUR_RADIUS_25: 218 mTest = new Blur25(false); 219 break; 220 case INTRINSIC_BLUE_RADIUS_25: 221 mTest = new Blur25(true); 222 break; 223 case GREYSCALE: 224 mTest = new Greyscale(); 225 break; 226 case GRAIN: 227 mTest = new Grain(); 228 break; 229 case FISHEYE_FULL: 230 mTest = new Fisheye(false, false); 231 break; 232 case FISHEYE_RELAXED: 233 mTest = new Fisheye(false, true); 234 break; 235 case FISHEYE_APPROXIMATE_FULL: 236 mTest = new Fisheye(true, false); 237 break; 238 case FISHEYE_APPROXIMATE_RELAXED: 239 mTest = new Fisheye(true, true); 240 break; 241 case VIGNETTE_FULL: 242 mTest = new Vignette(false, false); 243 break; 244 case VIGNETTE_RELAXED: 245 mTest = new Vignette(false, true); 246 break; 247 case VIGNETTE_APPROXIMATE_FULL: 248 mTest = new Vignette(true, false); 249 break; 250 case VIGNETTE_APPROXIMATE_RELAXED: 251 mTest = new Vignette(true, true); 252 break; 253 case GROUP_TEST_EMULATED: 254 mTest = new GroupTest(false); 255 break; 256 case GROUP_TEST_NATIVE: 257 mTest = new GroupTest(true); 258 break; 259 case CONVOLVE_3X3: 260 mTest = new Convolve3x3(false); 261 break; 262 case INTRINSICS_CONVOLVE_3X3: 263 mTest = new Convolve3x3(true); 264 break; 265 case COLOR_MATRIX: 266 mTest = new ColorMatrix(false, false); 267 break; 268 case INTRINSICS_COLOR_MATRIX: 269 mTest = new ColorMatrix(true, false); 270 break; 271 case INTRINSICS_COLOR_MATRIX_GREY: 272 mTest = new ColorMatrix(true, true); 273 break; 274 case COPY: 275 mTest = new Copy(); 276 break; 277 case CROSS_PROCESS_USING_LUT: 278 mTest = new CrossProcess(); 279 break; 280 case CONVOLVE_5X5: 281 mTest = new Convolve5x5(false); 282 break; 283 case INTRINSICS_CONVOLVE_5X5: 284 mTest = new Convolve5x5(true); 285 break; 286 case MANDELBROT: 287 mTest = new Mandelbrot(); 288 break; 289 case INTRINSICS_BLEND: 290 mTest = new Blend(); 291 break; 292 case INTRINSICS_BLUR_25G: 293 mTest = new Blur25G(); 294 break; 295 case VIBRANCE: 296 mTest = new Vibrance(); 297 break; 298 case BW_FILTER: 299 mTest = new BWFilter(); 300 break; 301 case SHADOWS: 302 mTest = new Shadows(); 303 break; 304 case CONTRAST: 305 mTest = new Contrast(); 306 break; 307 case EXPOSURE: 308 mTest = new Exposure(); 309 break; 310 case WHITE_BALANCE: 311 mTest = new WhiteBalance(); 312 break; 313 case COLOR_CUBE: 314 mTest = new ColorCube(false); 315 break; 316 case COLOR_CUBE_3D_INTRINSIC: 317 mTest = new ColorCube(true); 318 break; 319 } 320 321 mTest.createBaseTest(this, mBitmapIn, mBitmapIn2, mBitmapOut); 322 setupBars(); 323 324 mTest.runTest(); 325 updateDisplay(); 326 mBenchmarkResult.setText("Result: not run"); 327 } 328 329 void setupTests() { 330 mTestSpinner.setAdapter(new ArrayAdapter<TestName>( 331 this, R.layout.spinner_layout, TestName.values())); 332 } 333 334 private AdapterView.OnItemSelectedListener mTestSpinnerListener = 335 new AdapterView.OnItemSelectedListener() { 336 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 337 changeTest(TestName.values()[pos]); 338 } 339 340 public void onNothingSelected(AdapterView parent) { 341 342 } 343 }; 344 345 @Override 346 protected void onCreate(Bundle savedInstanceState) { 347 super.onCreate(savedInstanceState); 348 setContentView(R.layout.main); 349 350 mBitmapIn = loadBitmap(R.drawable.img1600x1067); 351 mBitmapIn2 = loadBitmap(R.drawable.img1600x1067b); 352 mBitmapOut = Bitmap.createBitmap(mBitmapIn.getWidth(), mBitmapIn.getHeight(), 353 mBitmapIn.getConfig()); 354 355 mSurfaceView = (SurfaceView) findViewById(R.id.surface); 356 357 mDisplayView = (ImageView) findViewById(R.id.display); 358 mDisplayView.setImageBitmap(mBitmapOut); 359 360 mSpinner = (Spinner) findViewById(R.id.spinner1); 361 362 mBar1 = (SeekBar) findViewById(R.id.slider1); 363 mBar2 = (SeekBar) findViewById(R.id.slider2); 364 mBar3 = (SeekBar) findViewById(R.id.slider3); 365 mBar4 = (SeekBar) findViewById(R.id.slider4); 366 mBar5 = (SeekBar) findViewById(R.id.slider5); 367 368 mBar1.setOnSeekBarChangeListener(this); 369 mBar2.setOnSeekBarChangeListener(this); 370 mBar3.setOnSeekBarChangeListener(this); 371 mBar4.setOnSeekBarChangeListener(this); 372 mBar5.setOnSeekBarChangeListener(this); 373 374 mText1 = (TextView) findViewById(R.id.slider1Text); 375 mText2 = (TextView) findViewById(R.id.slider2Text); 376 mText3 = (TextView) findViewById(R.id.slider3Text); 377 mText4 = (TextView) findViewById(R.id.slider4Text); 378 mText5 = (TextView) findViewById(R.id.slider5Text); 379 380 mTestSpinner = (Spinner) findViewById(R.id.filterselection); 381 mTestSpinner.setOnItemSelectedListener(mTestSpinnerListener); 382 383 mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); 384 mBenchmarkResult.setText("Result: not run"); 385 386 387 mRS = RenderScript.create(this); 388 mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn); 389 mInPixelsAllocation2 = Allocation.createFromBitmap(mRS, mBitmapIn2); 390 mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut); 391 392 393 setupTests(); 394 changeTest(TestName.LEVELS_VEC3_RELAXED); 395 } 396 397 398 private Bitmap loadBitmap(int resource) { 399 final BitmapFactory.Options options = new BitmapFactory.Options(); 400 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 401 return BitmapFactory.decodeResource(getResources(), resource, options); 402 } 403 404 // button hook 405 public void benchmark(View v) { 406 float t = getBenchmark(); 407 //long javaTime = javaFilter(); 408 //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); 409 mBenchmarkResult.setText("Result: " + t + " ms"); 410 Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t); 411 } 412 413 public void benchmark_all(View v) { 414 // write result into a file 415 File externalStorage = Environment.getExternalStorageDirectory(); 416 if (!externalStorage.canWrite()) { 417 Log.v(TAG, "sdcard is not writable"); 418 return; 419 } 420 File resultFile = new File(externalStorage, RESULT_FILE); 421 //resultFile.setWritable(true, false); 422 try { 423 BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile)); 424 Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath()); 425 for (TestName tn: TestName.values()) { 426 changeTest(tn); 427 float t = getBenchmark(); 428 String s = new String("" + tn.toString() + ", " + t); 429 rsWriter.write(s + "\n"); 430 Log.v(TAG, "Test " + s + "ms\n"); 431 } 432 rsWriter.close(); 433 } catch (IOException e) { 434 Log.v(TAG, "Unable to write result file " + e.getMessage()); 435 } 436 changeTest(TestName.LEVELS_VEC3_RELAXED); 437 } 438 439 // For benchmark test 440 public float getBenchmark() { 441 mDoingBenchmark = true; 442 443 mTest.setupBenchmark(); 444 long result = 0; 445 446 //Log.v(TAG, "Warming"); 447 long t = java.lang.System.currentTimeMillis() + 250; 448 do { 449 mTest.runTest(); 450 mTest.finish(); 451 } while (t > java.lang.System.currentTimeMillis()); 452 453 //Log.v(TAG, "Benchmarking"); 454 int ct = 0; 455 t = java.lang.System.currentTimeMillis(); 456 do { 457 mTest.runTest(); 458 mTest.finish(); 459 ct++; 460 } while ((t+1000) > java.lang.System.currentTimeMillis()); 461 t = java.lang.System.currentTimeMillis() - t; 462 float ft = (float)t; 463 ft /= ct; 464 465 mTest.exitBenchmark(); 466 mDoingBenchmark = false; 467 468 return ft; 469 } 470} 471