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