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