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