Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2016 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 android.view.cts;
     18 
     19 import android.opengl.GLSurfaceView;
     20 import android.util.Log;
     21 
     22 import javax.microedition.khronos.egl.EGLConfig;
     23 import javax.microedition.khronos.opengles.GL10;
     24 
     25 public class DisplayRefreshRateCtsActivity extends GLSurfaceViewCtsActivity {
     26     private static final String TAG = "DisplayRefreshRateAct";
     27 
     28     public class FpsResult {
     29         private float mFps;
     30         private boolean mValid = false;
     31         private boolean mRestartRequested = false;
     32 
     33         public final synchronized void notifyResult(float fps) {
     34             if (!mValid) {
     35                 mFps = fps;
     36                 mValid = true;
     37                 notifyAll();
     38             }
     39         }
     40 
     41         public final synchronized float waitResult() {
     42             while (!mValid) {
     43                 try {
     44                     wait();
     45                 } catch (InterruptedException e) {/* ignore and retry */}
     46             }
     47             return mFps;
     48         }
     49 
     50         public synchronized void restart() {
     51             mRestartRequested = true;
     52             mValid = false;
     53         }
     54         public synchronized boolean restartNecessary() {
     55             return mRestartRequested;
     56         }
     57         public synchronized void ackRestart() {
     58             mRestartRequested = false;
     59         }
     60     }
     61 
     62     private class Renderer implements GLSurfaceView.Renderer {
     63         // Measurement knobs.
     64         // NB: Some devices need a surprisingly long warmup period before the
     65         // framerate becomes stable.
     66         private static final float WARMUP_SECONDS = 2.0f;
     67         private static final float TEST_SECONDS   = 8.0f;
     68 
     69         // Test states
     70         private static final int STATE_START  = 0;
     71         private static final int STATE_WARMUP = 1;
     72         private static final int STATE_TEST   = 2;
     73         private static final int STATE_DONE   = 3;
     74 
     75         private FpsResult mResult;
     76         private int       mState     = STATE_START;
     77         private float     mStartTime = 0.0f;
     78         private int       mNumFrames = 0;
     79 
     80         public Renderer(FpsResult result) {
     81             mResult = result;
     82         }
     83 
     84         public void onDrawFrame(GL10 gl) {
     85             float t = (float)System.nanoTime() * 1.0e-9f;
     86             switch (mState) {
     87                 case STATE_START:
     88                     mStartTime = t;
     89                     mState = STATE_WARMUP;
     90                     break;
     91 
     92                 case STATE_WARMUP:
     93                     if ((t - mStartTime) >= WARMUP_SECONDS) {
     94                         mStartTime = t;
     95                         mNumFrames = 0;
     96                         mState = STATE_TEST;
     97                     }
     98                     break;
     99 
    100                 case STATE_TEST:
    101                     mNumFrames++;
    102                     float elapsed = t - mStartTime;
    103                     if (elapsed >= TEST_SECONDS) {
    104                         mResult.notifyResult((float)mNumFrames / elapsed);
    105                         mState = STATE_DONE;
    106                     }
    107                     break;
    108 
    109                 case STATE_DONE:
    110                     if (mResult.restartNecessary()) {
    111                         mResult.ackRestart();
    112                         mState = STATE_START;
    113                         Log.d(TAG, "restarting");
    114                     }
    115                     break;
    116             }
    117 
    118             // prevent unwanted optimizations or hidden costs (e.g. reading
    119             // previous frame on tilers).
    120             gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    121             gl.glClear(gl.GL_COLOR_BUFFER_BIT);
    122         }
    123 
    124         public void onSurfaceChanged(GL10 gl, int width, int height) {
    125             // Do nothing.
    126         }
    127 
    128         public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    129             // Do nothing.
    130         }
    131     }
    132 
    133     private FpsResult mResult = new FpsResult();
    134 
    135     @Override
    136     protected void configureGLSurfaceView() {
    137         mView.setRenderer(new Renderer(mResult));
    138         mView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    139     }
    140 
    141     public FpsResult getFpsResult() {
    142         return mResult;
    143     }
    144 }
    145