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.sgtest;
18
19import android.app.Activity;
20import android.os.Bundle;
21import android.os.Handler;
22import android.os.Message;
23import android.graphics.BitmapFactory;
24import android.graphics.Bitmap;
25import android.graphics.Canvas;
26import android.view.SurfaceView;
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 android.renderscript.ScriptC;
36import android.renderscript.RenderScript;
37import android.renderscript.Type;
38import android.renderscript.Allocation;
39import android.renderscript.Element;
40import android.renderscript.Script;
41
42import android.os.Environment;
43import java.io.BufferedWriter;
44import java.io.File;
45import java.io.FileWriter;
46import java.io.IOException;
47import java.util.ArrayList;
48
49public class ScriptGroupTestActivity extends Activity
50    implements SeekBar.OnSeekBarChangeListener {
51    private final String TAG = "Img";
52    public final String RESULT_FILE = "image_processing_result.csv";
53
54    RenderScript mRS;
55    Allocation mInPixelsAllocation;
56    Allocation mOutPixelsAllocation;
57
58    Bitmap mBitmapOut;
59
60    private Spinner mSpinner;
61
62    private TextView mBenchmarkResult;
63    private Spinner mModeSpinner;
64    private Spinner mTestSpinner1;
65    private Spinner mTestSpinner2;
66
67    private ImageView mDisplayView;
68
69    private boolean mDoingBenchmark;
70
71    private TestBase mTest;
72    private int mRunCount;
73
74    public void updateDisplay() {
75        mHandler.sendMessage(Message.obtain());
76    }
77
78    private Handler mHandler = new Handler() {
79        // Allow the filter to complete without blocking the UI
80        // thread.  When the message arrives that the op is complete
81        // we will either mark completion or start a new filter if
82        // more work is ready.  Either way, display the result.
83        @Override
84        public void handleMessage(Message msg) {
85            boolean doTest = false;
86            synchronized(this) {
87                if (mRS == null) {
88                    return;
89                }
90                mTest.updateBitmap(mBitmapOut);
91                mDisplayView.invalidate();
92                if (mRunCount > 0) {
93                    mRunCount--;
94                    if (mRunCount > 0) {
95                        doTest = true;
96                    }
97                }
98
99                if (doTest) {
100                    mTest.runTestSendMessage();
101                }
102            }
103        }
104
105    };
106
107    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
108    }
109
110    public void onStartTrackingTouch(SeekBar seekBar) {
111    }
112
113    public void onStopTrackingTouch(SeekBar seekBar) {
114    }
115
116  void changeTest(int pos1, int pos2, int mode) {
117    if (mTest != null) {
118      mTest.destroy();
119    }
120
121    final int[] index = new int[] { pos1, pos2 };
122    mTest = new Filters(mode, index);
123
124    mTest.createBaseTest(this);
125
126    mTest.runTest();
127    updateDisplay();
128    mBenchmarkResult.setText("Result: not run");
129  }
130
131  String getFilterName(int pos) {
132    return Filters.mFilterClasses[pos].getSimpleName();
133  }
134
135  String[] getFilterNames() {
136    ArrayList<String> list = new ArrayList<String>();
137    final int n = Filters.mFilterClasses.length;
138    for (int i = 0; i < n; i++) {
139      list.add(getFilterName(i));
140    }
141    return list.toArray(new String[0]);
142  }
143
144  void setupTests() {
145    String[] names = getFilterNames();
146    mModeSpinner.setAdapter(new ArrayAdapter<String>(
147        this, R.layout.spinner_layout, new String[] {"emulated", "native"}));
148    mTestSpinner1.setAdapter(new ArrayAdapter<String>(
149        this, R.layout.spinner_layout, names));
150    mTestSpinner2.setAdapter(new ArrayAdapter<String>(
151        this, R.layout.spinner_layout, names));
152  }
153
154  private AdapterView.OnItemSelectedListener mModeSpinnerListener =
155      new AdapterView.OnItemSelectedListener() {
156        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
157          changeTest(
158              mTestSpinner1.getSelectedItemPosition(),
159              mTestSpinner2.getSelectedItemPosition(),
160              pos);
161        }
162
163        public void onNothingSelected(AdapterView parent) {
164        }
165      };
166
167  private AdapterView.OnItemSelectedListener mTestSpinner1Listener =
168      new AdapterView.OnItemSelectedListener() {
169        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
170          changeTest(pos, mTestSpinner2.getSelectedItemPosition(),
171              mModeSpinner.getSelectedItemPosition());
172        }
173
174        public void onNothingSelected(AdapterView parent) {
175        }
176      };
177
178  private AdapterView.OnItemSelectedListener mTestSpinner2Listener =
179      new AdapterView.OnItemSelectedListener() {
180        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
181          changeTest(mTestSpinner1.getSelectedItemPosition(), pos,
182              mModeSpinner.getSelectedItemPosition());
183        }
184
185        public void onNothingSelected(AdapterView parent) {
186        }
187      };
188
189    void init() {
190        mRS = RenderScript.create(this);
191        mInPixelsAllocation = Allocation.createFromBitmapResource(
192                mRS, getResources(), R.drawable.img1600x1067);
193        mBitmapOut = Bitmap.createBitmap(mInPixelsAllocation.getType().getX(),
194                                         mInPixelsAllocation.getType().getY(),
195                                         Bitmap.Config.ARGB_8888);
196        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut);
197
198        mDisplayView = findViewById(R.id.display);
199        mDisplayView.setImageBitmap(mBitmapOut);
200
201        mModeSpinner = findViewById(R.id.modeselection);
202        mModeSpinner.setOnItemSelectedListener(mModeSpinnerListener);
203        mTestSpinner1 = findViewById(R.id.filterselection);
204        mTestSpinner1.setOnItemSelectedListener(mTestSpinner1Listener);
205        mTestSpinner2 = findViewById(R.id.filter2selection);
206        mTestSpinner2.setOnItemSelectedListener(mTestSpinner2Listener);
207
208        mBenchmarkResult = findViewById(R.id.benchmarkText);
209        mBenchmarkResult.setText("Result: not run");
210
211        setupTests();
212        changeTest(0, 0, 0);
213    }
214
215    void cleanup() {
216        synchronized(this) {
217            RenderScript rs = mRS;
218            mRS = null;
219            while(mDoingBenchmark) {
220                try {
221                    Thread.sleep(1, 0);
222                } catch(InterruptedException e) {
223                }
224
225            }
226            rs.destroy();
227        }
228
229        mInPixelsAllocation = null;
230        mOutPixelsAllocation = null;
231        mBitmapOut = null;
232    }
233
234    @Override
235    protected void onCreate(Bundle savedInstanceState) {
236        super.onCreate(savedInstanceState);
237        setContentView(R.layout.main);
238
239        init();
240    }
241
242    @Override
243    protected void onPause() {
244        super.onPause();
245
246        cleanup();
247    }
248
249
250    @Override
251    protected void onResume() {
252        super.onResume();
253
254        if (null == mRS) {
255            init();
256        }
257    }
258
259    // button hook
260    public void benchmark(View v) {
261        float t = getBenchmark();
262        //long javaTime = javaFilter();
263        //mBenchmarkResult.setText("RS: " + t + " ms  Java: " + javaTime + " ms");
264        mBenchmarkResult.setText("Result: " + t + " ms");
265        Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t);
266    }
267
268    public void benchmark_all(View v) {
269        // write result into a file
270        File externalStorage = Environment.getExternalStorageDirectory();
271        if (!externalStorage.canWrite()) {
272            Log.v(TAG, "sdcard is not writable");
273            return;
274        }
275        File resultFile = new File(externalStorage, RESULT_FILE);
276        resultFile.setWritable(true, false);
277        try {
278            BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile));
279            Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath());
280            final int n = Filters.mFilterClasses.length;
281            for (int i = 0; i < n; i++) {
282              for (int j = 0; j < n; j++) {
283                for (int k = 0; k < 2; k++) {
284                  changeTest(i, j, k);
285                float t = getBenchmark();
286                String tn = getFilterName(i) + "-" + getFilterName(j);
287                if (k == 0) {
288                  tn += " (emulated)";
289                } else {
290                  tn += " (native)";
291                }
292                String s = new String("" + tn.toString() + ", " + t);
293                rsWriter.write(s + "\n");
294                Log.v(TAG, "Test " + s + "ms\n");
295                }
296              }
297            }
298            rsWriter.close();
299        } catch (IOException e) {
300            Log.v(TAG, "Unable to write result file " + e.getMessage());
301        }
302            changeTest(0, 0, 0);
303        Log.v(TAG, "result file:"+resultFile.getAbsolutePath());
304    }
305
306
307
308    // For benchmark test
309    public float getBenchmark() {
310        if (mRS == null) {
311            return 0;
312        }
313        mDoingBenchmark = true;
314
315        mTest.setupBenchmark();
316        long result = 0;
317
318        //Log.v(TAG, "Warming");
319        long t = java.lang.System.currentTimeMillis() + 250;
320        do {
321            mTest.runTest();
322            mTest.finish();
323        } while (t > java.lang.System.currentTimeMillis());
324
325        //Log.v(TAG, "Benchmarking");
326        int ct = 0;
327        t = java.lang.System.currentTimeMillis();
328        do {
329            mTest.runTest();
330            mTest.finish();
331            ct++;
332        } while ((t+1000) > java.lang.System.currentTimeMillis());
333        t = java.lang.System.currentTimeMillis() - t;
334        float ft = (float)t;
335        ft /= ct;
336
337        mTest.exitBenchmark();
338        mDoingBenchmark = false;
339
340        return ft;
341    }
342}
343