/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.rs.sgtest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.graphics.BitmapFactory; import android.graphics.Bitmap; import android.graphics.Canvas; import android.view.SurfaceView; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.SeekBar; import android.widget.Spinner; import android.widget.TextView; import android.view.View; import android.util.Log; import android.renderscript.ScriptC; import android.renderscript.RenderScript; import android.renderscript.Type; import android.renderscript.Allocation; import android.renderscript.Element; import android.renderscript.Script; import android.os.Environment; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; public class ScriptGroupTestActivity extends Activity implements SeekBar.OnSeekBarChangeListener { private final String TAG = "Img"; public final String RESULT_FILE = "image_processing_result.csv"; RenderScript mRS; Allocation mInPixelsAllocation; Allocation mOutPixelsAllocation; Bitmap mBitmapOut; private Spinner mSpinner; private TextView mBenchmarkResult; private Spinner mModeSpinner; private Spinner mTestSpinner1; private Spinner mTestSpinner2; private ImageView mDisplayView; private boolean mDoingBenchmark; private TestBase mTest; private int mRunCount; public void updateDisplay() { mHandler.sendMessage(Message.obtain()); } private Handler mHandler = new Handler() { // Allow the filter to complete without blocking the UI // thread. When the message arrives that the op is complete // we will either mark completion or start a new filter if // more work is ready. Either way, display the result. @Override public void handleMessage(Message msg) { boolean doTest = false; synchronized(this) { if (mRS == null) { return; } mTest.updateBitmap(mBitmapOut); mDisplayView.invalidate(); if (mRunCount > 0) { mRunCount--; if (mRunCount > 0) { doTest = true; } } if (doTest) { mTest.runTestSendMessage(); } } } }; public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { } public void onStartTrackingTouch(SeekBar seekBar) { } public void onStopTrackingTouch(SeekBar seekBar) { } void changeTest(int pos1, int pos2, int mode) { if (mTest != null) { mTest.destroy(); } final int[] index = new int[] { pos1, pos2 }; mTest = new Filters(mode, index); mTest.createBaseTest(this); mTest.runTest(); updateDisplay(); mBenchmarkResult.setText("Result: not run"); } String getFilterName(int pos) { return Filters.mFilterClasses[pos].getSimpleName(); } String[] getFilterNames() { ArrayList list = new ArrayList(); final int n = Filters.mFilterClasses.length; for (int i = 0; i < n; i++) { list.add(getFilterName(i)); } return list.toArray(new String[0]); } void setupTests() { String[] names = getFilterNames(); mModeSpinner.setAdapter(new ArrayAdapter( this, R.layout.spinner_layout, new String[] {"emulated", "native"})); mTestSpinner1.setAdapter(new ArrayAdapter( this, R.layout.spinner_layout, names)); mTestSpinner2.setAdapter(new ArrayAdapter( this, R.layout.spinner_layout, names)); } private AdapterView.OnItemSelectedListener mModeSpinnerListener = new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int pos, long id) { changeTest( mTestSpinner1.getSelectedItemPosition(), mTestSpinner2.getSelectedItemPosition(), pos); } public void onNothingSelected(AdapterView parent) { } }; private AdapterView.OnItemSelectedListener mTestSpinner1Listener = new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int pos, long id) { changeTest(pos, mTestSpinner2.getSelectedItemPosition(), mModeSpinner.getSelectedItemPosition()); } public void onNothingSelected(AdapterView parent) { } }; private AdapterView.OnItemSelectedListener mTestSpinner2Listener = new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View view, int pos, long id) { changeTest(mTestSpinner1.getSelectedItemPosition(), pos, mModeSpinner.getSelectedItemPosition()); } public void onNothingSelected(AdapterView parent) { } }; void init() { mRS = RenderScript.create(this); mInPixelsAllocation = Allocation.createFromBitmapResource( mRS, getResources(), R.drawable.img1600x1067); mBitmapOut = Bitmap.createBitmap(mInPixelsAllocation.getType().getX(), mInPixelsAllocation.getType().getY(), Bitmap.Config.ARGB_8888); mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut); mDisplayView = (ImageView) findViewById(R.id.display); mDisplayView.setImageBitmap(mBitmapOut); mModeSpinner = (Spinner) findViewById(R.id.modeselection); mModeSpinner.setOnItemSelectedListener(mModeSpinnerListener); mTestSpinner1 = (Spinner) findViewById(R.id.filterselection); mTestSpinner1.setOnItemSelectedListener(mTestSpinner1Listener); mTestSpinner2 = (Spinner) findViewById(R.id.filter2selection); mTestSpinner2.setOnItemSelectedListener(mTestSpinner2Listener); mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); mBenchmarkResult.setText("Result: not run"); setupTests(); changeTest(0, 0, 0); } void cleanup() { synchronized(this) { RenderScript rs = mRS; mRS = null; while(mDoingBenchmark) { try { Thread.sleep(1, 0); } catch(InterruptedException e) { } } rs.destroy(); } mInPixelsAllocation = null; mOutPixelsAllocation = null; mBitmapOut = null; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } @Override protected void onPause() { super.onPause(); cleanup(); } @Override protected void onResume() { super.onResume(); if (null == mRS) { init(); } } // button hook public void benchmark(View v) { float t = getBenchmark(); //long javaTime = javaFilter(); //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); mBenchmarkResult.setText("Result: " + t + " ms"); Log.v(TAG, "getBenchmark: Renderscript frame time core ms " + t); } public void benchmark_all(View v) { // write result into a file File externalStorage = Environment.getExternalStorageDirectory(); if (!externalStorage.canWrite()) { Log.v(TAG, "sdcard is not writable"); return; } File resultFile = new File(externalStorage, RESULT_FILE); resultFile.setWritable(true, false); try { BufferedWriter rsWriter = new BufferedWriter(new FileWriter(resultFile)); Log.v(TAG, "Saved results in: " + resultFile.getAbsolutePath()); final int n = Filters.mFilterClasses.length; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < 2; k++) { changeTest(i, j, k); float t = getBenchmark(); String tn = getFilterName(i) + "-" + getFilterName(j); if (k == 0) { tn += " (emulated)"; } else { tn += " (native)"; } String s = new String("" + tn.toString() + ", " + t); rsWriter.write(s + "\n"); Log.v(TAG, "Test " + s + "ms\n"); } } } rsWriter.close(); } catch (IOException e) { Log.v(TAG, "Unable to write result file " + e.getMessage()); } changeTest(0, 0, 0); Log.v(TAG, "result file:"+resultFile.getAbsolutePath()); } // For benchmark test public float getBenchmark() { if (mRS == null) { return 0; } mDoingBenchmark = true; mTest.setupBenchmark(); long result = 0; //Log.v(TAG, "Warming"); long t = java.lang.System.currentTimeMillis() + 250; do { mTest.runTest(); mTest.finish(); } while (t > java.lang.System.currentTimeMillis()); //Log.v(TAG, "Benchmarking"); int ct = 0; t = java.lang.System.currentTimeMillis(); do { mTest.runTest(); mTest.finish(); ct++; } while ((t+1000) > java.lang.System.currentTimeMillis()); t = java.lang.System.currentTimeMillis() - t; float ft = (float)t; ft /= ct; mTest.exitBenchmark(); mDoingBenchmark = false; return ft; } }