1 /* 2 * Copyright (C) 2019 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 package com.android.game.qualification.tests; 17 18 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; 19 20 import android.content.Context; 21 import android.os.Bundle; 22 import android.util.AttributeSet; 23 import android.view.SurfaceHolder; 24 import android.view.SurfaceView; 25 26 import java.util.ArrayDeque; 27 import java.util.Queue; 28 29 /** 30 * Test activity to retrieve frame ready time and buffer latch time. 31 */ 32 public class SurfaceFlingerTestActivity extends TestActivity { 33 private final String LOG_TAG = "SurfaceFlingerTestActivity"; 34 35 private TestView mView; 36 37 private Queue<Long> mReadyTimes = new ArrayDeque<>(); 38 private Queue<Long> mLatchTimes = new ArrayDeque<>(); 39 40 @Override onCreate(Bundle savedInstanceState)41 protected void onCreate(Bundle savedInstanceState) { 42 super.onCreate(savedInstanceState); 43 44 mView = new TestView(this); 45 mView.setSystemUiVisibility(SYSTEM_UI_FLAG_FULLSCREEN); 46 setContentView(mView); 47 } 48 49 @Override onPause()50 protected void onPause() { 51 super.onPause(); 52 } 53 54 @Override onResume()55 protected void onResume() { 56 super.onResume(); 57 } 58 getReadyTimes()59 public Queue<Long> getReadyTimes() { 60 return mReadyTimes; 61 } 62 getLatchTimes()63 public Queue<Long> getLatchTimes() { 64 return mLatchTimes; 65 } 66 67 private class TestView extends SurfaceView implements Runnable { 68 private volatile boolean mRunning = true; 69 private Thread mThread; TestView(Context context)70 public TestView(Context context) { 71 super(context); 72 73 getHolder().addCallback(new SurfaceHolder.Callback() { 74 @Override 75 public void surfaceCreated(SurfaceHolder holder) { 76 mRunning = true; 77 mThread = new Thread(TestView.this); 78 mThread.start(); 79 } 80 81 @Override 82 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 83 } 84 85 @Override 86 public void surfaceDestroyed(SurfaceHolder holder) { 87 try { 88 mRunning = false; 89 mThread.join(); 90 } catch (InterruptedException e) { 91 throw new RuntimeException(e); 92 } 93 } 94 }); 95 } 96 TestView(Context context, AttributeSet attrs)97 public TestView(Context context, AttributeSet attrs) { 98 super(context, attrs); 99 } 100 TestView(Context context, AttributeSet attrs, int defStyleAttr)101 public TestView(Context context, AttributeSet attrs, int defStyleAttr) { 102 super(context, attrs, defStyleAttr); 103 } 104 TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)105 public TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 106 super(context, attrs, defStyleAttr, defStyleRes); 107 } 108 109 @Override run()110 public void run() { 111 if (getHolder().getSurface().isValid()) { 112 initDisplay(getHolder().getSurface()); 113 114 while (mRunning) { 115 drawFrame(); 116 long[] frameData = getFrameData(); 117 while (frameData != null) { 118 // Limit the number of frames to 240 to avoid infinitely growing buffer. 119 int MAX_FRAMES = 240; 120 if (getReadyTimes().size() == MAX_FRAMES) { 121 getReadyTimes().poll(); 122 getLatchTimes().poll(); 123 } 124 getReadyTimes().offer(frameData[0]); 125 getLatchTimes().offer(frameData[1]); 126 frameData = getFrameData(); 127 } 128 } 129 } 130 } 131 } 132 initDisplay(Object surface)133 public native void initDisplay(Object surface); drawFrame()134 public native void drawFrame(); getFrameData()135 public native long[] getFrameData(); 136 } 137