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