Home | History | Annotate | Download | only in image
      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 
     17 package com.android.rs.imagejb;
     18 
     19 import android.app.Activity;
     20 
     21 import android.content.Intent;
     22 import android.os.Bundle;
     23 import android.widget.SeekBar;
     24 import android.widget.Spinner;
     25 import android.widget.TextView;
     26 import android.view.View;
     27 import android.view.TextureView;
     28 import android.view.Surface;
     29 import android.graphics.SurfaceTexture;
     30 import android.graphics.Point;
     31 import android.view.WindowManager;
     32 
     33 import android.util.Log;
     34 import android.renderscript.Allocation;
     35 import android.renderscript.RenderScript;
     36 import android.support.test.InstrumentationRegistry;
     37 
     38 public class ImageProcessingActivityJB extends Activity
     39                                        implements SeekBar.OnSeekBarChangeListener,
     40                                                   TextureView.SurfaceTextureListener {
     41     private final String TAG = "Img";
     42 
     43     private Spinner mSpinner;
     44     private SeekBar mBar1;
     45     private SeekBar mBar2;
     46     private SeekBar mBar3;
     47     private SeekBar mBar4;
     48     private SeekBar mBar5;
     49 
     50     private int mBars[] = new int[5];
     51     private int mBarsOld[] = new int[5];
     52 
     53     private TextView mText1;
     54     private TextView mText2;
     55     private TextView mText3;
     56     private TextView mText4;
     57     private TextView mText5;
     58     private SizedTV mDisplayView;
     59 
     60     private int mTestList[];
     61     private float mTestResults[];
     62 
     63     private boolean mToggleIO;
     64     private boolean mToggleDVFS;
     65     private boolean mToggleLong;
     66     private boolean mTogglePause;
     67     private boolean mToggleAnimate;
     68     private boolean mToggleDisplay;
     69     private int mBitmapWidth;
     70     private int mBitmapHeight;
     71     private boolean mDemoMode;
     72     private float mMinTestRuntime;
     73     private int mMinTestIterations;
     74 
     75     // Updates pending is a counter of how many kernels have been
     76     // sent to RS for processing
     77     //
     78     // In benchmark this is incremented each time a kernel is launched and
     79     // decremented each time a kernel completes
     80     //
     81     // In demo mode, each UI input increments the counter and it is zeroed
     82     // when the latest settings are sent to RS for processing.
     83     private int mUpdatesPending;
     84 
     85     // In demo mode this is used to count updates in the pipeline.  It's
     86     // incremented when work is submitted to RS and decremented when invalidate is
     87     // called to display a result.
     88     private int mShowsPending;
     89 
     90     // Initialize the parameters for Instrumentation tests.
     91     protected void prepareInstrumentationTest() {
     92         mTestList = new int[1];
     93         mBitmapWidth = 1920;
     94         mBitmapHeight = 1080;
     95         mTestResults = new float[1];
     96 
     97         startProcessor();
     98     }
     99 
    100     static public class SizedTV extends TextureView {
    101         int mWidth;
    102         int mHeight;
    103 
    104         public SizedTV(android.content.Context c) {
    105             super(c);
    106             mWidth = 800;
    107             mHeight = 450;
    108         }
    109 
    110         public SizedTV(android.content.Context c, android.util.AttributeSet attrs) {
    111             super(c, attrs);
    112             mWidth = 800;
    113             mHeight = 450;
    114         }
    115 
    116         public SizedTV(android.content.Context c, android.util.AttributeSet attrs, int f) {
    117             super(c, attrs, f);
    118             mWidth = 800;
    119             mHeight = 450;
    120         }
    121 
    122         protected void onMeasure(int w, int h) {
    123             setMeasuredDimension(mWidth, mHeight);
    124         }
    125     }
    126 
    127     /////////////////////////////////////////////////////////////////////////
    128 
    129     // Message processor to handle notifications for when kernel completes
    130     private class MessageProcessor extends RenderScript.RSMessageHandler {
    131         MessageProcessor() {
    132         }
    133 
    134         public void run() {
    135             synchronized(mProcessor) {
    136                 // In demo mode, decrement the pending displays and notify the
    137                 // UI processor it can now enqueue more work if additional updates
    138                 // are blocked by a full pipeline.
    139                 if (mShowsPending > 0) {
    140                     mShowsPending --;
    141                     mProcessor.notifyAll();
    142                 }
    143             }
    144         }
    145     }
    146 
    147 
    148     /////////////////////////////////////////////////////////////////////////
    149     // Processor is a helper thread for running the work without
    150     // blocking the UI thread.
    151     class Processor extends Thread {
    152         RenderScript mRS;
    153         Allocation mInPixelsAllocation;
    154         Allocation mInPixelsAllocation2;
    155         Allocation mOutDisplayAllocation;
    156         Allocation mOutPixelsAllocation;
    157 
    158         private Surface mOutSurface;
    159         private float mLastResult;
    160         private boolean mRun = true;
    161         private boolean mDoingBenchmark;
    162         private TestBase mTest;
    163         private TextureView mDisplayView;
    164 
    165         private boolean mBenchmarkMode;
    166 
    167         // We don't want to call the "changed" methods excessively as this
    168         // can cause extra work for drivers.  Before running a test update
    169         // any bars which have changed.
    170         void runTest() {
    171             if (mBars[0] != mBarsOld[0]) {
    172                 mTest.onBar1Changed(mBars[0]);
    173                 mBarsOld[0] = mBars[0];
    174             }
    175             if (mBars[1] != mBarsOld[1]) {
    176                 mTest.onBar2Changed(mBars[1]);
    177                 mBarsOld[1] = mBars[1];
    178             }
    179             if (mBars[2] != mBarsOld[2]) {
    180                 mTest.onBar3Changed(mBars[2]);
    181                 mBarsOld[2] = mBars[2];
    182             }
    183             if (mBars[3] != mBarsOld[3]) {
    184                 mTest.onBar4Changed(mBars[3]);
    185                 mBarsOld[3] = mBars[3];
    186             }
    187             if (mBars[4] != mBarsOld[4]) {
    188                 mTest.onBar5Changed(mBars[4]);
    189                 mBarsOld[4] = mBars[4];
    190             }
    191             mTest.runTest();
    192         }
    193 
    194         Processor(RenderScript rs, TextureView v, boolean benchmarkMode) {
    195             mRS = rs;
    196             mDisplayView = v;
    197 
    198             mRS.setMessageHandler(new MessageProcessor());
    199 
    200             switch(mBitmapWidth) {
    201             case 3840:
    202                 mInPixelsAllocation = Allocation.createFromBitmapResource(
    203                         mRS, getResources(), R.drawable.img3840x2160a);
    204                 mInPixelsAllocation2 = Allocation.createFromBitmapResource(
    205                         mRS, getResources(), R.drawable.img3840x2160b);
    206                 break;
    207             case 1920:
    208                 mInPixelsAllocation = Allocation.createFromBitmapResource(
    209                         mRS, getResources(), R.drawable.img1920x1080a);
    210                 mInPixelsAllocation2 = Allocation.createFromBitmapResource(
    211                         mRS, getResources(), R.drawable.img1920x1080b);
    212                 break;
    213             case 1280:
    214                 mInPixelsAllocation = Allocation.createFromBitmapResource(
    215                         mRS, getResources(), R.drawable.img1280x720a);
    216                 mInPixelsAllocation2 = Allocation.createFromBitmapResource(
    217                         mRS, getResources(), R.drawable.img1280x720b);
    218                 break;
    219             case 800:
    220                 mInPixelsAllocation = Allocation.createFromBitmapResource(
    221                         mRS, getResources(), R.drawable.img800x450a);
    222                 mInPixelsAllocation2 = Allocation.createFromBitmapResource(
    223                         mRS, getResources(), R.drawable.img800x450b);
    224                 break;
    225             }
    226 
    227             // We create the output allocation using USAGE_IO_OUTPUT so we can share the
    228             // bits with a TextureView.  This is more efficient than using a bitmap.
    229             mOutDisplayAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(),
    230                                                                Allocation.MipmapControl.MIPMAP_NONE,
    231                                                                Allocation.USAGE_SCRIPT |
    232                                                                Allocation.USAGE_IO_OUTPUT);
    233             mOutPixelsAllocation = mOutDisplayAllocation;
    234 
    235             if (!mToggleIO) {
    236                 // Not using USAGE_IO for the script so create a non-io kernel to copy from
    237                 mOutPixelsAllocation = Allocation.createTyped(mRS, mInPixelsAllocation.getType(),
    238                                                               Allocation.MipmapControl.MIPMAP_NONE,
    239                                                               Allocation.USAGE_SCRIPT);
    240             }
    241 
    242             mBenchmarkMode = benchmarkMode;
    243             start();
    244         }
    245 
    246         // Run one loop of kernels for at least the specified minimum time.
    247         // The function returns the average time in ms for the test run
    248         private Result runBenchmarkLoop(float minTime, int minIter) {
    249             mUpdatesPending = 0;
    250             Result r = new Result();
    251 
    252             long t = java.lang.System.nanoTime();
    253             do {
    254                 synchronized(this) {
    255                     // Shows pending is used to track the number of kernels in the RS pipeline
    256                     // We throttle it to 2.  This provide some buffering to allow a kernel to be started
    257                     // before we are nofitied the previous finished.  However, larger numbers are uncommon
    258                     // in interactive apps as they introduce 'lag' between user input and display.
    259                     mShowsPending++;
    260                     if (mShowsPending > 2) {
    261                         try {
    262                             this.wait();
    263                         } catch(InterruptedException e) {
    264                         }
    265                     }
    266                 }
    267 
    268                 // If animations are enabled update the test state.
    269                 if (mToggleAnimate) {
    270                     mTest.animateBars(r.getTotalTime());
    271                 }
    272 
    273                 // Run the kernel
    274                 mTest.runTest();
    275 
    276                 if (mToggleDisplay) {
    277                     // If we are not outputting directly to the TextureView we need to copy from
    278                     // our temporary buffer.
    279                     if (mOutDisplayAllocation != mOutPixelsAllocation) {
    280                         mOutDisplayAllocation.copyFrom(mOutPixelsAllocation);
    281                     }
    282 
    283                     // queue the update of the TextureView with the allocation contents
    284                     mOutDisplayAllocation.ioSend();
    285                 }
    286 
    287                 // Send our RS message handler a message so we know when this work has completed
    288                 mRS.sendMessage(0, null);
    289 
    290                 // Finish previous iteration before recording the time. Without this, the first
    291                 // few iterations finish very quickly and the later iterations take much longer
    292                 mRS.finish();
    293 
    294                 long t2 = java.lang.System.nanoTime();
    295                 r.add((t2 - t) / 1000000000.f);
    296                 t = t2;
    297             } while (r.getTotalTime() < minTime || r.getIterations() < minIter);
    298 
    299             // Wait for any stray operations to complete and update the final time
    300             mRS.finish();
    301             return r;
    302         }
    303 
    304         // Method to retreive benchmark results for instrumentation tests.
    305         Result getInstrumentationResult(IPTestListJB.TestName t) {
    306             mTest = changeTest(t, false);
    307             return getBenchmark();
    308         }
    309 
    310         // Get a benchmark result for a specific test
    311         private Result getBenchmark() {
    312             mDoingBenchmark = true;
    313             mUpdatesPending = 0;
    314 
    315             if (mToggleDVFS) {
    316                 mDvfsWar.go();
    317             }
    318 
    319             // We run a short bit of work before starting the actual test
    320             // this is to let any power management do its job and respond
    321             runBenchmarkLoop(0.3f, 0);
    322 
    323             // Run the actual benchmark
    324             Result r = runBenchmarkLoop(mMinTestRuntime, mMinTestIterations);
    325 
    326             Log.v("rs", "Test: time=" + r.getTotalTime() + "s,  frames=" + r.getIterations() +
    327                   ", avg=" + r.getAvg() * 1000.f + ", stdcoef=" + r.getStdCoef() * 100.0f + "%");
    328 
    329             mDoingBenchmark = false;
    330             return r;
    331         }
    332 
    333         public void run() {
    334             Surface lastSurface = null;
    335             while (mRun) {
    336                 // Our loop for launching tests or benchmarks
    337                 synchronized(this) {
    338                     // If we have no work to do, or we have displays pending, wait
    339                     if ((mUpdatesPending == 0) || (mShowsPending != 0)) {
    340                         try {
    341                             this.wait();
    342                         } catch(InterruptedException e) {
    343                         }
    344                     }
    345 
    346                     // We may have been asked to exit while waiting
    347                     if (!mRun) return;
    348 
    349                     // During startup we may not have a surface yet to display, if
    350                     // this is the case, wait.
    351                     if ((mOutSurface == null) || (mOutPixelsAllocation == null)) {
    352                         continue;
    353                     }
    354 
    355                     // Our display surface changed, set it.
    356                     if (lastSurface != mOutSurface) {
    357                         mOutDisplayAllocation.setSurface(mOutSurface);
    358                         lastSurface = mOutSurface;
    359                     }
    360                 }
    361 
    362                 if (mBenchmarkMode) {
    363                     // Loop over the tests we want to benchmark
    364                     for (int ct=0; (ct < mTestList.length) && mRun; ct++) {
    365 
    366                         // For reproducibility we wait a short time for any sporadic work
    367                         // created by the user touching the screen to launch the test to pass.
    368                         // Also allows for things to settle after the test changes.
    369                         mRS.finish();
    370                         try {
    371                             sleep(250);
    372                         } catch(InterruptedException e) {
    373                         }
    374 
    375                         // If we just ran a test, we destroy it here to relieve some memory pressure
    376                         if (mTest != null) {
    377                             mTest.destroy();
    378                         }
    379 
    380                         // Select the next test
    381                         mTest = changeTest(mTestList[ct], false);
    382 
    383                         // If the user selected the "long pause" option, wait
    384                         if (mTogglePause) {
    385                             for (int i=0; (i < 100) && mRun; i++) {
    386                                 try {
    387                                     sleep(100);
    388                                 } catch(InterruptedException e) {
    389                                 }
    390                             }
    391                         }
    392 
    393                         // Run the test
    394                         mTestResults[ct] = getBenchmark().getAvg() * 1000.0f;
    395                     }
    396                     onBenchmarkFinish(mRun);
    397                 } else {
    398                     boolean update = false;
    399                     synchronized(this) {
    400                         // If we have updates to process and are not blocked by pending shows,
    401                         // start the next kernel
    402                         if ((mUpdatesPending > 0) && (mShowsPending == 0)) {
    403                             mUpdatesPending = 0;
    404                             update = true;
    405                             mShowsPending++;
    406                         }
    407                     }
    408 
    409                     if (update) {
    410                         // Run the kernel
    411                         runTest();
    412 
    413                         // If we are not outputting directly to the TextureView we need to copy from
    414                         // our temporary buffer.
    415                         if (mOutDisplayAllocation != mOutPixelsAllocation) {
    416                             mOutDisplayAllocation.copyFrom(mOutPixelsAllocation);
    417                         }
    418 
    419                         // queue the update of the TextureView with the allocation contents
    420                         mOutDisplayAllocation.ioSend();
    421 
    422                         // Send our RS message handler a message so we know when this work has completed
    423                         mRS.sendMessage(0, null);
    424                     }
    425                 }
    426             }
    427 
    428         }
    429 
    430         public void update() {
    431             // something UI related has changed, enqueue an update if one is not
    432             // already pending.  Wake the worker if needed
    433             synchronized(this) {
    434                 if (mUpdatesPending < 2) {
    435                     mUpdatesPending++;
    436                     notifyAll();
    437                 }
    438             }
    439         }
    440 
    441         public void setSurface(Surface s) {
    442             mOutSurface = s;
    443             update();
    444         }
    445 
    446         public void exit() {
    447             mRun = false;
    448 
    449             synchronized(this) {
    450                 notifyAll();
    451             }
    452 
    453             try {
    454                 this.join();
    455             } catch(InterruptedException e) {
    456             }
    457 
    458             mInPixelsAllocation.destroy();
    459             mInPixelsAllocation2.destroy();
    460             if (mOutPixelsAllocation != mOutDisplayAllocation) {
    461                 mOutPixelsAllocation.destroy();
    462             }
    463 
    464             if (mTest != null) {
    465                 mTest.destroy();
    466                 mTest = null;
    467             }
    468             mOutDisplayAllocation.destroy();
    469             mRS.destroy();
    470 
    471             mInPixelsAllocation = null;
    472             mInPixelsAllocation2 = null;
    473             mOutPixelsAllocation = null;
    474             mOutDisplayAllocation = null;
    475             mRS = null;
    476         }
    477     }
    478 
    479     ///////////////////////////////////////////////////////////////////////////////////////
    480 
    481     static class DVFSWorkaround {
    482         static class spinner extends Thread {
    483             boolean mRun = true;
    484             long mNextSleep;
    485 
    486             spinner() {
    487                 setPriority(MIN_PRIORITY);
    488                 start();
    489             }
    490 
    491             public void run() {
    492                 while (mRun) {
    493                     Thread.yield();
    494                     synchronized(this) {
    495                         long t = java.lang.System.currentTimeMillis();
    496                         if (t > mNextSleep) {
    497                             try {
    498                                 this.wait();
    499                             } catch(InterruptedException e) {
    500                             }
    501                         }
    502                     }
    503                 }
    504             }
    505 
    506             public void go(long t) {
    507                 synchronized(this) {
    508                     mNextSleep = t;
    509                     notifyAll();
    510                 }
    511             }
    512         }
    513 
    514         spinner s1;
    515         DVFSWorkaround() {
    516             s1 = new spinner();
    517         }
    518 
    519         void go() {
    520             long t = java.lang.System.currentTimeMillis() + 2000;
    521             s1.go(t);
    522         }
    523 
    524         void destroy() {
    525             synchronized(this) {
    526                 s1.mRun = false;
    527                 notifyAll();
    528             }
    529         }
    530     }
    531     DVFSWorkaround mDvfsWar = new DVFSWorkaround();
    532 
    533     ///////////////////////////////////////////////////////////
    534 
    535 
    536     private boolean mDoingBenchmark;
    537     public Processor mProcessor;
    538 
    539     TestBase changeTest(IPTestListJB.TestName t, boolean setupUI) {
    540         TestBase tb = IPTestListJB.newTest(t);
    541 
    542         tb.createBaseTest(this);
    543         if (setupUI) {
    544             setupBars(tb);
    545         }
    546         return tb;
    547     }
    548 
    549     TestBase changeTest(int id, boolean setupUI) {
    550         IPTestListJB.TestName t = IPTestListJB.TestName.values()[id];
    551         return changeTest(t, setupUI);
    552     }
    553 
    554     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    555         if (fromUser) {
    556             if (seekBar == mBar1) {
    557                 mBars[0] = progress;
    558             } else if (seekBar == mBar2) {
    559                 mBars[1] = progress;
    560             } else if (seekBar == mBar3) {
    561                 mBars[2] = progress;
    562             } else if (seekBar == mBar4) {
    563                 mBars[3] = progress;
    564             } else if (seekBar == mBar5) {
    565                 mBars[4] = progress;
    566             }
    567             mProcessor.update();
    568         }
    569     }
    570 
    571     public void onStartTrackingTouch(SeekBar seekBar) {
    572     }
    573 
    574     public void onStopTrackingTouch(SeekBar seekBar) {
    575     }
    576 
    577     void setupBars(TestBase t) {
    578         mSpinner.setVisibility(View.VISIBLE);
    579         t.onSpinner1Setup(mSpinner);
    580 
    581         mBar1.setVisibility(View.VISIBLE);
    582         mText1.setVisibility(View.VISIBLE);
    583         t.onBar1Setup(mBar1, mText1);
    584 
    585         mBar2.setVisibility(View.VISIBLE);
    586         mText2.setVisibility(View.VISIBLE);
    587         t.onBar2Setup(mBar2, mText2);
    588 
    589         mBar3.setVisibility(View.VISIBLE);
    590         mText3.setVisibility(View.VISIBLE);
    591         t.onBar3Setup(mBar3, mText3);
    592 
    593         mBar4.setVisibility(View.VISIBLE);
    594         mText4.setVisibility(View.VISIBLE);
    595         t.onBar4Setup(mBar4, mText4);
    596 
    597         mBar5.setVisibility(View.VISIBLE);
    598         mText5.setVisibility(View.VISIBLE);
    599         t.onBar5Setup(mBar5, mText5);
    600     }
    601 
    602     void hideBars() {
    603         mSpinner.setVisibility(View.INVISIBLE);
    604 
    605         mBar1.setVisibility(View.INVISIBLE);
    606         mText1.setVisibility(View.INVISIBLE);
    607 
    608         mBar2.setVisibility(View.INVISIBLE);
    609         mText2.setVisibility(View.INVISIBLE);
    610 
    611         mBar3.setVisibility(View.INVISIBLE);
    612         mText3.setVisibility(View.INVISIBLE);
    613 
    614         mBar4.setVisibility(View.INVISIBLE);
    615         mText4.setVisibility(View.INVISIBLE);
    616 
    617         mBar5.setVisibility(View.INVISIBLE);
    618         mText5.setVisibility(View.INVISIBLE);
    619     }
    620 
    621     @Override
    622     protected void onCreate(Bundle savedInstanceState) {
    623         super.onCreate(savedInstanceState);
    624         setContentView(R.layout.main);
    625         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    626 
    627         mDisplayView = findViewById(R.id.display);
    628 
    629         mSpinner = findViewById(R.id.spinner1);
    630 
    631         mBar1 = findViewById(R.id.slider1);
    632         mBar2 = findViewById(R.id.slider2);
    633         mBar3 = findViewById(R.id.slider3);
    634         mBar4 = findViewById(R.id.slider4);
    635         mBar5 = findViewById(R.id.slider5);
    636 
    637         mBar1.setOnSeekBarChangeListener(this);
    638         mBar2.setOnSeekBarChangeListener(this);
    639         mBar3.setOnSeekBarChangeListener(this);
    640         mBar4.setOnSeekBarChangeListener(this);
    641         mBar5.setOnSeekBarChangeListener(this);
    642 
    643         mText1 = findViewById(R.id.slider1Text);
    644         mText2 = findViewById(R.id.slider2Text);
    645         mText3 = findViewById(R.id.slider3Text);
    646         mText4 = findViewById(R.id.slider4Text);
    647         mText5 = findViewById(R.id.slider5Text);
    648     }
    649 
    650     @Override
    651     protected void onPause() {
    652         super.onPause();
    653         if (mProcessor != null) {
    654             mProcessor.exit();
    655             mProcessor = null;
    656         }
    657     }
    658 
    659     public void onBenchmarkFinish(boolean ok) {
    660         if (ok) {
    661             Intent intent = new Intent();
    662             intent.putExtra("tests", mTestList);
    663             intent.putExtra("results", mTestResults);
    664             setResult(RESULT_OK, intent);
    665         } else {
    666             setResult(RESULT_CANCELED);
    667         }
    668         finish();
    669     }
    670 
    671 
    672     void startProcessor() {
    673         Point size = new Point();
    674         getWindowManager().getDefaultDisplay().getSize(size);
    675 
    676         int mScreenWidth = size.x;
    677         int mScreenHeight = size.y;
    678 
    679         int tw = mBitmapWidth;
    680         int th = mBitmapHeight;
    681 
    682         if (tw > mScreenWidth || th > mScreenHeight) {
    683             float s1 = (float)tw / (float)mScreenWidth;
    684             float s2 = (float)th / (float)mScreenHeight;
    685 
    686             if (s1 > s2) {
    687                 tw /= s1;
    688                 th /= s1;
    689             } else {
    690                 tw /= s2;
    691                 th /= s2;
    692             }
    693         }
    694 
    695         android.util.Log.v("rs", "TV sizes " + tw + ", " + th);
    696 
    697         mDisplayView.mWidth = tw;
    698         mDisplayView.mHeight = th;
    699         //mDisplayView.setTransform(new android.graphics.Matrix());
    700 
    701         mProcessor = new Processor(RenderScript.create(this), mDisplayView, !mDemoMode);
    702         mDisplayView.setSurfaceTextureListener(this);
    703 
    704         if (mDemoMode) {
    705             mProcessor.mTest = changeTest(mTestList[0], true);
    706         }
    707     }
    708 
    709     @Override
    710     protected void onResume() {
    711         super.onResume();
    712         Intent i = getIntent();
    713         mTestList = i.getIntArrayExtra("tests");
    714 
    715         mToggleIO = i.getBooleanExtra("enable io", false);
    716         mToggleDVFS = i.getBooleanExtra("enable dvfs", false);
    717         mToggleLong = i.getBooleanExtra("enable long", false);
    718         mTogglePause = i.getBooleanExtra("enable pause", false);
    719         mToggleAnimate = i.getBooleanExtra("enable animate", false);
    720         mToggleDisplay = i.getBooleanExtra("enable display", false);
    721         mBitmapWidth = i.getIntExtra("resolution X", 0);
    722         mBitmapHeight = i.getIntExtra("resolution Y", 0);
    723         mDemoMode = i.getBooleanExtra("demo", false);
    724 
    725         // Default values
    726         mMinTestRuntime = 1.0f;
    727         mMinTestIterations = 2;
    728 
    729         // Pass in arguments from "am instrumentation ..." if present
    730         // This is wrapped in a try..catch because there was an exception thrown whenever
    731         // instrumentation was not used (ie. when the graphical interface was used)
    732         try {
    733             Bundle extras = InstrumentationRegistry.getArguments();
    734             String passedInString = null;
    735             if ( extras != null ) {
    736                 if ( extras.containsKey ("minimum_test_runtime") ) {
    737                     mMinTestRuntime = Float.parseFloat(extras.getString("minimum_test_runtime"));
    738                 }
    739                 if ( extras.containsKey ("minimum_test_iterations") ) {
    740                     mMinTestIterations = Integer.parseInt(
    741                             extras.getString("minimum_test_iterations"));
    742                 }
    743             }
    744         } catch(Exception e) {
    745         }
    746 
    747         // User chose the longer pre-set runtime
    748         if (mToggleLong) {
    749             mMinTestRuntime = 10.f;
    750         }
    751 
    752         // Hide the bars in demo mode.
    753         // Calling from onResume() to make sure the operation is on the UI thread.
    754         if (!mDemoMode) {
    755             hideBars();
    756         }
    757         // Start the processor only when a non-empty list received from the intent.
    758         if (mTestList != null) {
    759             mTestResults = new float[mTestList.length];
    760             startProcessor();
    761         }
    762     }
    763 
    764     protected void onDestroy() {
    765         super.onDestroy();
    766     }
    767 
    768 
    769     @Override
    770     public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    771         mProcessor.setSurface(new Surface(surface));
    772     }
    773 
    774     @Override
    775     public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    776         mProcessor.setSurface(new Surface(surface));
    777     }
    778 
    779     @Override
    780     public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    781         if (mProcessor != null) {
    782             mProcessor.setSurface(null);
    783         }
    784         return true;
    785     }
    786 
    787     @Override
    788     public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    789     }
    790 }
    791