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