xref: /aosp_15_r20/frameworks/native/cmds/flatland/Main.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2012 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_ALWAYS
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceControl.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <gui/GLConsumer.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <ui/Fence.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <EGL/egl.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker #include <math.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <getopt.h>
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker #include "Flatland.h"
34*38e8c45fSAndroid Build Coastguard Worker #include "GLHelper.h"
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker using namespace ::android;
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker static uint32_t    g_SleepBetweenSamplesMs = 0;
39*38e8c45fSAndroid Build Coastguard Worker static bool        g_PresentToWindow       = false;
40*38e8c45fSAndroid Build Coastguard Worker static size_t      g_BenchmarkNameLen      = 0;
41*38e8c45fSAndroid Build Coastguard Worker static sp<IBinder> g_DisplayToken          = nullptr;
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker struct BenchmarkDesc {
44*38e8c45fSAndroid Build Coastguard Worker     // The name of the test.
45*38e8c45fSAndroid Build Coastguard Worker     const char* name;
46*38e8c45fSAndroid Build Coastguard Worker 
47*38e8c45fSAndroid Build Coastguard Worker     // The dimensions of the space in which window layers are specified.
48*38e8c45fSAndroid Build Coastguard Worker     uint32_t width;
49*38e8c45fSAndroid Build Coastguard Worker     uint32_t height;
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker     // The screen heights at which to run the test.
52*38e8c45fSAndroid Build Coastguard Worker     uint32_t runHeights[MAX_TEST_RUNS];
53*38e8c45fSAndroid Build Coastguard Worker 
54*38e8c45fSAndroid Build Coastguard Worker     // The list of window layers.
55*38e8c45fSAndroid Build Coastguard Worker     LayerDesc layers[MAX_NUM_LAYERS];
56*38e8c45fSAndroid Build Coastguard Worker };
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker static const BenchmarkDesc benchmarks[] = {
59*38e8c45fSAndroid Build Coastguard Worker     { "16:10 Single Static Window",
60*38e8c45fSAndroid Build Coastguard Worker         2560, 1600, { 800, 1200, 1600, 2400 },
61*38e8c45fSAndroid Build Coastguard Worker         {
62*38e8c45fSAndroid Build Coastguard Worker             {   // Window
63*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
64*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2560,   1454,
65*38e8c45fSAndroid Build Coastguard Worker             },
66*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
67*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
68*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2560,   50,
69*38e8c45fSAndroid Build Coastguard Worker             },
70*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
71*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
72*38e8c45fSAndroid Build Coastguard Worker                 0,    1504,   2560,   96,
73*38e8c45fSAndroid Build Coastguard Worker             },
74*38e8c45fSAndroid Build Coastguard Worker         },
75*38e8c45fSAndroid Build Coastguard Worker     },
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker     { "4:3 Single Static Window",
78*38e8c45fSAndroid Build Coastguard Worker         2048, 1536, { 1536 },
79*38e8c45fSAndroid Build Coastguard Worker         {
80*38e8c45fSAndroid Build Coastguard Worker             {   // Window
81*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
82*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2048,   1440,
83*38e8c45fSAndroid Build Coastguard Worker             },
84*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
85*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
86*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2048,   50,
87*38e8c45fSAndroid Build Coastguard Worker             },
88*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
89*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
90*38e8c45fSAndroid Build Coastguard Worker                 0,    1440,   2048,   96,
91*38e8c45fSAndroid Build Coastguard Worker             },
92*38e8c45fSAndroid Build Coastguard Worker         },
93*38e8c45fSAndroid Build Coastguard Worker     },
94*38e8c45fSAndroid Build Coastguard Worker 
95*38e8c45fSAndroid Build Coastguard Worker     { "16:10 App -> Home Transition",
96*38e8c45fSAndroid Build Coastguard Worker         2560, 1600, { 800, 1200, 1600, 2400 },
97*38e8c45fSAndroid Build Coastguard Worker         {
98*38e8c45fSAndroid Build Coastguard Worker             {   // Wallpaper
99*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
100*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2560,   1454,
101*38e8c45fSAndroid Build Coastguard Worker             },
102*38e8c45fSAndroid Build Coastguard Worker             {   // Launcher
103*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blend,
104*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2560,   1454,
105*38e8c45fSAndroid Build Coastguard Worker             },
106*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing activity
107*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
108*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2520,   1414,
109*38e8c45fSAndroid Build Coastguard Worker             },
110*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
111*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
112*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2560,   50,
113*38e8c45fSAndroid Build Coastguard Worker             },
114*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
115*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
116*38e8c45fSAndroid Build Coastguard Worker                 0,    1504,   2560,   96,
117*38e8c45fSAndroid Build Coastguard Worker             },
118*38e8c45fSAndroid Build Coastguard Worker         },
119*38e8c45fSAndroid Build Coastguard Worker     },
120*38e8c45fSAndroid Build Coastguard Worker 
121*38e8c45fSAndroid Build Coastguard Worker     { "4:3 App -> Home Transition",
122*38e8c45fSAndroid Build Coastguard Worker         2048, 1536, { 1536 },
123*38e8c45fSAndroid Build Coastguard Worker         {
124*38e8c45fSAndroid Build Coastguard Worker             {   // Wallpaper
125*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
126*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2048,   1440,
127*38e8c45fSAndroid Build Coastguard Worker             },
128*38e8c45fSAndroid Build Coastguard Worker             {   // Launcher
129*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blend,
130*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2048,   1440,
131*38e8c45fSAndroid Build Coastguard Worker             },
132*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing activity
133*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
134*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2048,   1400,
135*38e8c45fSAndroid Build Coastguard Worker             },
136*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
137*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
138*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2048,   50,
139*38e8c45fSAndroid Build Coastguard Worker             },
140*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
141*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
142*38e8c45fSAndroid Build Coastguard Worker                 0,    1440,   2048,   96,
143*38e8c45fSAndroid Build Coastguard Worker             },
144*38e8c45fSAndroid Build Coastguard Worker         },
145*38e8c45fSAndroid Build Coastguard Worker     },
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker     { "16:10 SurfaceView -> Home Transition",
148*38e8c45fSAndroid Build Coastguard Worker         2560, 1600, { 800, 1200, 1600, 2400 },
149*38e8c45fSAndroid Build Coastguard Worker         {
150*38e8c45fSAndroid Build Coastguard Worker             {   // Wallpaper
151*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
152*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2560,   1454,
153*38e8c45fSAndroid Build Coastguard Worker             },
154*38e8c45fSAndroid Build Coastguard Worker             {   // Launcher
155*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blend,
156*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2560,   1454,
157*38e8c45fSAndroid Build Coastguard Worker             },
158*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing SurfaceView
159*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
160*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2520,   1414,
161*38e8c45fSAndroid Build Coastguard Worker             },
162*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing activity
163*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
164*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2520,   1414,
165*38e8c45fSAndroid Build Coastguard Worker             },
166*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
167*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
168*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2560,   50,
169*38e8c45fSAndroid Build Coastguard Worker             },
170*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
171*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
172*38e8c45fSAndroid Build Coastguard Worker                 0,    1504,   2560,   96,
173*38e8c45fSAndroid Build Coastguard Worker             },
174*38e8c45fSAndroid Build Coastguard Worker         },
175*38e8c45fSAndroid Build Coastguard Worker     },
176*38e8c45fSAndroid Build Coastguard Worker 
177*38e8c45fSAndroid Build Coastguard Worker     { "4:3 SurfaceView -> Home Transition",
178*38e8c45fSAndroid Build Coastguard Worker         2048, 1536, { 1536 },
179*38e8c45fSAndroid Build Coastguard Worker         {
180*38e8c45fSAndroid Build Coastguard Worker             {   // Wallpaper
181*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
182*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2048,   1440,
183*38e8c45fSAndroid Build Coastguard Worker             },
184*38e8c45fSAndroid Build Coastguard Worker             {   // Launcher
185*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blend,
186*38e8c45fSAndroid Build Coastguard Worker                 0,    50,     2048,   1440,
187*38e8c45fSAndroid Build Coastguard Worker             },
188*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing SurfaceView
189*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
190*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2048,   1400,
191*38e8c45fSAndroid Build Coastguard Worker             },
192*38e8c45fSAndroid Build Coastguard Worker             {   // Outgoing activity
193*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, blendShrink,
194*38e8c45fSAndroid Build Coastguard Worker                 20,    70,     2048,   1400,
195*38e8c45fSAndroid Build Coastguard Worker             },
196*38e8c45fSAndroid Build Coastguard Worker             {   // Status bar
197*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
198*38e8c45fSAndroid Build Coastguard Worker                 0,    0,      2048,   50,
199*38e8c45fSAndroid Build Coastguard Worker             },
200*38e8c45fSAndroid Build Coastguard Worker             {   // Navigation bar
201*38e8c45fSAndroid Build Coastguard Worker                 0, staticGradient, opaque,
202*38e8c45fSAndroid Build Coastguard Worker                 0,    1440,   2048,   96,
203*38e8c45fSAndroid Build Coastguard Worker             },
204*38e8c45fSAndroid Build Coastguard Worker         },
205*38e8c45fSAndroid Build Coastguard Worker     },
206*38e8c45fSAndroid Build Coastguard Worker };
207*38e8c45fSAndroid Build Coastguard Worker 
208*38e8c45fSAndroid Build Coastguard Worker static const ShaderDesc shaders[] = {
209*38e8c45fSAndroid Build Coastguard Worker     {
210*38e8c45fSAndroid Build Coastguard Worker         .name="Blit",
211*38e8c45fSAndroid Build Coastguard Worker         .vertexShader={
212*38e8c45fSAndroid Build Coastguard Worker             "precision mediump float;",
213*38e8c45fSAndroid Build Coastguard Worker             "",
214*38e8c45fSAndroid Build Coastguard Worker             "attribute vec4 position;",
215*38e8c45fSAndroid Build Coastguard Worker             "attribute vec4 uv;",
216*38e8c45fSAndroid Build Coastguard Worker             "",
217*38e8c45fSAndroid Build Coastguard Worker             "varying vec4 texCoords;",
218*38e8c45fSAndroid Build Coastguard Worker             "",
219*38e8c45fSAndroid Build Coastguard Worker             "uniform mat4 objToNdc;",
220*38e8c45fSAndroid Build Coastguard Worker             "uniform mat4 uvToTex;",
221*38e8c45fSAndroid Build Coastguard Worker             "",
222*38e8c45fSAndroid Build Coastguard Worker             "void main() {",
223*38e8c45fSAndroid Build Coastguard Worker             "    gl_Position = objToNdc * position;",
224*38e8c45fSAndroid Build Coastguard Worker             "    texCoords = uvToTex * uv;",
225*38e8c45fSAndroid Build Coastguard Worker             "}",
226*38e8c45fSAndroid Build Coastguard Worker         },
227*38e8c45fSAndroid Build Coastguard Worker         .fragmentShader={
228*38e8c45fSAndroid Build Coastguard Worker             "#extension GL_OES_EGL_image_external : require",
229*38e8c45fSAndroid Build Coastguard Worker             "precision mediump float;",
230*38e8c45fSAndroid Build Coastguard Worker             "",
231*38e8c45fSAndroid Build Coastguard Worker             "varying vec4 texCoords;",
232*38e8c45fSAndroid Build Coastguard Worker             "",
233*38e8c45fSAndroid Build Coastguard Worker             "uniform samplerExternalOES blitSrc;",
234*38e8c45fSAndroid Build Coastguard Worker             "uniform vec4 modColor;",
235*38e8c45fSAndroid Build Coastguard Worker             "",
236*38e8c45fSAndroid Build Coastguard Worker             "void main() {",
237*38e8c45fSAndroid Build Coastguard Worker             "    gl_FragColor = texture2D(blitSrc, texCoords.xy);",
238*38e8c45fSAndroid Build Coastguard Worker             "    gl_FragColor *= modColor;",
239*38e8c45fSAndroid Build Coastguard Worker             "}",
240*38e8c45fSAndroid Build Coastguard Worker         },
241*38e8c45fSAndroid Build Coastguard Worker     },
242*38e8c45fSAndroid Build Coastguard Worker 
243*38e8c45fSAndroid Build Coastguard Worker     {
244*38e8c45fSAndroid Build Coastguard Worker         .name="Gradient",
245*38e8c45fSAndroid Build Coastguard Worker         .vertexShader={
246*38e8c45fSAndroid Build Coastguard Worker             "precision mediump float;",
247*38e8c45fSAndroid Build Coastguard Worker             "",
248*38e8c45fSAndroid Build Coastguard Worker             "attribute vec4 position;",
249*38e8c45fSAndroid Build Coastguard Worker             "attribute vec4 uv;",
250*38e8c45fSAndroid Build Coastguard Worker             "",
251*38e8c45fSAndroid Build Coastguard Worker             "varying float interp;",
252*38e8c45fSAndroid Build Coastguard Worker             "",
253*38e8c45fSAndroid Build Coastguard Worker             "uniform mat4 objToNdc;",
254*38e8c45fSAndroid Build Coastguard Worker             "uniform mat4 uvToInterp;",
255*38e8c45fSAndroid Build Coastguard Worker             "",
256*38e8c45fSAndroid Build Coastguard Worker             "void main() {",
257*38e8c45fSAndroid Build Coastguard Worker             "    gl_Position = objToNdc * position;",
258*38e8c45fSAndroid Build Coastguard Worker             "    interp = (uvToInterp * uv).x;",
259*38e8c45fSAndroid Build Coastguard Worker             "}",
260*38e8c45fSAndroid Build Coastguard Worker         },
261*38e8c45fSAndroid Build Coastguard Worker         .fragmentShader={
262*38e8c45fSAndroid Build Coastguard Worker             "precision mediump float;",
263*38e8c45fSAndroid Build Coastguard Worker             "",
264*38e8c45fSAndroid Build Coastguard Worker             "varying float interp;",
265*38e8c45fSAndroid Build Coastguard Worker             "",
266*38e8c45fSAndroid Build Coastguard Worker             "uniform vec4 color0;",
267*38e8c45fSAndroid Build Coastguard Worker             "uniform vec4 color1;",
268*38e8c45fSAndroid Build Coastguard Worker             "",
269*38e8c45fSAndroid Build Coastguard Worker             "uniform sampler2D ditherKernel;",
270*38e8c45fSAndroid Build Coastguard Worker             "uniform float invDitherKernelSize;",
271*38e8c45fSAndroid Build Coastguard Worker             "uniform float invDitherKernelSizeSq;",
272*38e8c45fSAndroid Build Coastguard Worker             "",
273*38e8c45fSAndroid Build Coastguard Worker             "void main() {",
274*38e8c45fSAndroid Build Coastguard Worker             "    float dither = texture2D(ditherKernel,",
275*38e8c45fSAndroid Build Coastguard Worker             "            gl_FragCoord.xy * invDitherKernelSize).a;",
276*38e8c45fSAndroid Build Coastguard Worker             "    dither *= invDitherKernelSizeSq;",
277*38e8c45fSAndroid Build Coastguard Worker             "    vec4 color = mix(color0, color1, clamp(interp, 0.0, 1.0));",
278*38e8c45fSAndroid Build Coastguard Worker             "    gl_FragColor = color + vec4(dither, dither, dither, 0.0);",
279*38e8c45fSAndroid Build Coastguard Worker             "}",
280*38e8c45fSAndroid Build Coastguard Worker         },
281*38e8c45fSAndroid Build Coastguard Worker     },
282*38e8c45fSAndroid Build Coastguard Worker };
283*38e8c45fSAndroid Build Coastguard Worker 
284*38e8c45fSAndroid Build Coastguard Worker class Layer {
285*38e8c45fSAndroid Build Coastguard Worker 
286*38e8c45fSAndroid Build Coastguard Worker public:
287*38e8c45fSAndroid Build Coastguard Worker 
Layer()288*38e8c45fSAndroid Build Coastguard Worker     Layer() :
289*38e8c45fSAndroid Build Coastguard Worker         mGLHelper(nullptr),
290*38e8c45fSAndroid Build Coastguard Worker         mSurface(EGL_NO_SURFACE) {
291*38e8c45fSAndroid Build Coastguard Worker     }
292*38e8c45fSAndroid Build Coastguard Worker 
setUp(const LayerDesc & desc,GLHelper * helper)293*38e8c45fSAndroid Build Coastguard Worker     bool setUp(const LayerDesc& desc, GLHelper* helper) {
294*38e8c45fSAndroid Build Coastguard Worker         bool result;
295*38e8c45fSAndroid Build Coastguard Worker 
296*38e8c45fSAndroid Build Coastguard Worker         mDesc = desc;
297*38e8c45fSAndroid Build Coastguard Worker         mGLHelper = helper;
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker         result = mGLHelper->createSurfaceTexture(mDesc.width, mDesc.height,
300*38e8c45fSAndroid Build Coastguard Worker                 &mGLConsumer, &mSurface, &mTexName);
301*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
302*38e8c45fSAndroid Build Coastguard Worker             return false;
303*38e8c45fSAndroid Build Coastguard Worker         }
304*38e8c45fSAndroid Build Coastguard Worker 
305*38e8c45fSAndroid Build Coastguard Worker         mRenderer = desc.rendererFactory();
306*38e8c45fSAndroid Build Coastguard Worker         result = mRenderer->setUp(helper);
307*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
308*38e8c45fSAndroid Build Coastguard Worker             return false;
309*38e8c45fSAndroid Build Coastguard Worker         }
310*38e8c45fSAndroid Build Coastguard Worker 
311*38e8c45fSAndroid Build Coastguard Worker         mComposer = desc.composerFactory();
312*38e8c45fSAndroid Build Coastguard Worker         result = mComposer->setUp(desc, helper);
313*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
314*38e8c45fSAndroid Build Coastguard Worker             return false;
315*38e8c45fSAndroid Build Coastguard Worker         }
316*38e8c45fSAndroid Build Coastguard Worker 
317*38e8c45fSAndroid Build Coastguard Worker         return true;
318*38e8c45fSAndroid Build Coastguard Worker     }
319*38e8c45fSAndroid Build Coastguard Worker 
tearDown()320*38e8c45fSAndroid Build Coastguard Worker     void tearDown() {
321*38e8c45fSAndroid Build Coastguard Worker         if (mComposer != nullptr) {
322*38e8c45fSAndroid Build Coastguard Worker             mComposer->tearDown();
323*38e8c45fSAndroid Build Coastguard Worker             delete mComposer;
324*38e8c45fSAndroid Build Coastguard Worker             mComposer = nullptr;
325*38e8c45fSAndroid Build Coastguard Worker         }
326*38e8c45fSAndroid Build Coastguard Worker 
327*38e8c45fSAndroid Build Coastguard Worker         if (mRenderer != nullptr) {
328*38e8c45fSAndroid Build Coastguard Worker             mRenderer->tearDown();
329*38e8c45fSAndroid Build Coastguard Worker             delete mRenderer;
330*38e8c45fSAndroid Build Coastguard Worker             mRenderer = nullptr;
331*38e8c45fSAndroid Build Coastguard Worker         }
332*38e8c45fSAndroid Build Coastguard Worker 
333*38e8c45fSAndroid Build Coastguard Worker         if (mSurface != EGL_NO_SURFACE) {
334*38e8c45fSAndroid Build Coastguard Worker             mGLHelper->destroySurface(&mSurface);
335*38e8c45fSAndroid Build Coastguard Worker             mGLConsumer->abandon();
336*38e8c45fSAndroid Build Coastguard Worker         }
337*38e8c45fSAndroid Build Coastguard Worker         mGLHelper = nullptr;
338*38e8c45fSAndroid Build Coastguard Worker         mGLConsumer.clear();
339*38e8c45fSAndroid Build Coastguard Worker     }
340*38e8c45fSAndroid Build Coastguard Worker 
render()341*38e8c45fSAndroid Build Coastguard Worker     bool render() {
342*38e8c45fSAndroid Build Coastguard Worker         return mRenderer->render(mSurface);
343*38e8c45fSAndroid Build Coastguard Worker     }
344*38e8c45fSAndroid Build Coastguard Worker 
prepareComposition()345*38e8c45fSAndroid Build Coastguard Worker     bool prepareComposition() {
346*38e8c45fSAndroid Build Coastguard Worker         status_t err;
347*38e8c45fSAndroid Build Coastguard Worker 
348*38e8c45fSAndroid Build Coastguard Worker         err = mGLConsumer->updateTexImage();
349*38e8c45fSAndroid Build Coastguard Worker         if (err < 0) {
350*38e8c45fSAndroid Build Coastguard Worker             fprintf(stderr, "GLConsumer::updateTexImage error: %d\n", err);
351*38e8c45fSAndroid Build Coastguard Worker             return false;
352*38e8c45fSAndroid Build Coastguard Worker         }
353*38e8c45fSAndroid Build Coastguard Worker 
354*38e8c45fSAndroid Build Coastguard Worker         return true;
355*38e8c45fSAndroid Build Coastguard Worker     }
356*38e8c45fSAndroid Build Coastguard Worker 
compose()357*38e8c45fSAndroid Build Coastguard Worker     bool compose() {
358*38e8c45fSAndroid Build Coastguard Worker         return mComposer->compose(mTexName, mGLConsumer);
359*38e8c45fSAndroid Build Coastguard Worker     }
360*38e8c45fSAndroid Build Coastguard Worker 
361*38e8c45fSAndroid Build Coastguard Worker private:
362*38e8c45fSAndroid Build Coastguard Worker     LayerDesc mDesc;
363*38e8c45fSAndroid Build Coastguard Worker 
364*38e8c45fSAndroid Build Coastguard Worker     GLHelper* mGLHelper;
365*38e8c45fSAndroid Build Coastguard Worker 
366*38e8c45fSAndroid Build Coastguard Worker     GLuint mTexName;
367*38e8c45fSAndroid Build Coastguard Worker     sp<GLConsumer> mGLConsumer;
368*38e8c45fSAndroid Build Coastguard Worker     EGLSurface mSurface;
369*38e8c45fSAndroid Build Coastguard Worker 
370*38e8c45fSAndroid Build Coastguard Worker     Renderer* mRenderer;
371*38e8c45fSAndroid Build Coastguard Worker     Composer* mComposer;
372*38e8c45fSAndroid Build Coastguard Worker };
373*38e8c45fSAndroid Build Coastguard Worker 
374*38e8c45fSAndroid Build Coastguard Worker class BenchmarkRunner {
375*38e8c45fSAndroid Build Coastguard Worker 
376*38e8c45fSAndroid Build Coastguard Worker public:
377*38e8c45fSAndroid Build Coastguard Worker 
BenchmarkRunner(const BenchmarkDesc & desc,size_t instance)378*38e8c45fSAndroid Build Coastguard Worker     BenchmarkRunner(const BenchmarkDesc& desc, size_t instance) :
379*38e8c45fSAndroid Build Coastguard Worker         mDesc(desc),
380*38e8c45fSAndroid Build Coastguard Worker         mInstance(instance),
381*38e8c45fSAndroid Build Coastguard Worker         mNumLayers(countLayers(desc)),
382*38e8c45fSAndroid Build Coastguard Worker         mGLHelper(nullptr),
383*38e8c45fSAndroid Build Coastguard Worker         mSurface(EGL_NO_SURFACE),
384*38e8c45fSAndroid Build Coastguard Worker         mWindowSurface(EGL_NO_SURFACE) {
385*38e8c45fSAndroid Build Coastguard Worker     }
386*38e8c45fSAndroid Build Coastguard Worker 
setUp()387*38e8c45fSAndroid Build Coastguard Worker     bool setUp() {
388*38e8c45fSAndroid Build Coastguard Worker         ATRACE_CALL();
389*38e8c45fSAndroid Build Coastguard Worker 
390*38e8c45fSAndroid Build Coastguard Worker         bool result;
391*38e8c45fSAndroid Build Coastguard Worker 
392*38e8c45fSAndroid Build Coastguard Worker         float scaleFactor = float(mDesc.runHeights[mInstance]) /
393*38e8c45fSAndroid Build Coastguard Worker             float(mDesc.height);
394*38e8c45fSAndroid Build Coastguard Worker         uint32_t w = uint32_t(scaleFactor * float(mDesc.width));
395*38e8c45fSAndroid Build Coastguard Worker         uint32_t h = mDesc.runHeights[mInstance];
396*38e8c45fSAndroid Build Coastguard Worker 
397*38e8c45fSAndroid Build Coastguard Worker         mGLHelper = new GLHelper();
398*38e8c45fSAndroid Build Coastguard Worker         result = mGLHelper->setUp(g_DisplayToken, shaders, NELEMS(shaders));
399*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
400*38e8c45fSAndroid Build Coastguard Worker             return false;
401*38e8c45fSAndroid Build Coastguard Worker         }
402*38e8c45fSAndroid Build Coastguard Worker 
403*38e8c45fSAndroid Build Coastguard Worker         GLuint texName;
404*38e8c45fSAndroid Build Coastguard Worker         result = mGLHelper->createSurfaceTexture(w, h, &mGLConsumer, &mSurface,
405*38e8c45fSAndroid Build Coastguard Worker                 &texName);
406*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
407*38e8c45fSAndroid Build Coastguard Worker             return false;
408*38e8c45fSAndroid Build Coastguard Worker         }
409*38e8c45fSAndroid Build Coastguard Worker 
410*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNumLayers; i++) {
411*38e8c45fSAndroid Build Coastguard Worker             // Scale the layer to match the current screen size.
412*38e8c45fSAndroid Build Coastguard Worker             LayerDesc ld = mDesc.layers[i];
413*38e8c45fSAndroid Build Coastguard Worker             ld.x = int32_t(scaleFactor * float(ld.x));
414*38e8c45fSAndroid Build Coastguard Worker             ld.y = int32_t(scaleFactor * float(ld.y));
415*38e8c45fSAndroid Build Coastguard Worker             ld.width = uint32_t(scaleFactor * float(ld.width));
416*38e8c45fSAndroid Build Coastguard Worker             ld.height = uint32_t(scaleFactor * float(ld.height));
417*38e8c45fSAndroid Build Coastguard Worker 
418*38e8c45fSAndroid Build Coastguard Worker             // Set up the layer.
419*38e8c45fSAndroid Build Coastguard Worker             result = mLayers[i].setUp(ld, mGLHelper);
420*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
421*38e8c45fSAndroid Build Coastguard Worker                 return false;
422*38e8c45fSAndroid Build Coastguard Worker             }
423*38e8c45fSAndroid Build Coastguard Worker         }
424*38e8c45fSAndroid Build Coastguard Worker 
425*38e8c45fSAndroid Build Coastguard Worker         if (g_PresentToWindow) {
426*38e8c45fSAndroid Build Coastguard Worker             result = mGLHelper->createWindowSurface(w, h, &mSurfaceControl,
427*38e8c45fSAndroid Build Coastguard Worker                     &mWindowSurface);
428*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
429*38e8c45fSAndroid Build Coastguard Worker                 return false;
430*38e8c45fSAndroid Build Coastguard Worker             }
431*38e8c45fSAndroid Build Coastguard Worker 
432*38e8c45fSAndroid Build Coastguard Worker             result = doFrame(mWindowSurface);
433*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
434*38e8c45fSAndroid Build Coastguard Worker                 return false;
435*38e8c45fSAndroid Build Coastguard Worker             }
436*38e8c45fSAndroid Build Coastguard Worker         }
437*38e8c45fSAndroid Build Coastguard Worker 
438*38e8c45fSAndroid Build Coastguard Worker         return true;
439*38e8c45fSAndroid Build Coastguard Worker     }
440*38e8c45fSAndroid Build Coastguard Worker 
tearDown()441*38e8c45fSAndroid Build Coastguard Worker     void tearDown() {
442*38e8c45fSAndroid Build Coastguard Worker         ATRACE_CALL();
443*38e8c45fSAndroid Build Coastguard Worker 
444*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNumLayers; i++) {
445*38e8c45fSAndroid Build Coastguard Worker             mLayers[i].tearDown();
446*38e8c45fSAndroid Build Coastguard Worker         }
447*38e8c45fSAndroid Build Coastguard Worker 
448*38e8c45fSAndroid Build Coastguard Worker         if (mGLHelper != nullptr) {
449*38e8c45fSAndroid Build Coastguard Worker             if (mWindowSurface != EGL_NO_SURFACE) {
450*38e8c45fSAndroid Build Coastguard Worker                 mGLHelper->destroySurface(&mWindowSurface);
451*38e8c45fSAndroid Build Coastguard Worker             }
452*38e8c45fSAndroid Build Coastguard Worker             mGLHelper->destroySurface(&mSurface);
453*38e8c45fSAndroid Build Coastguard Worker             mGLConsumer->abandon();
454*38e8c45fSAndroid Build Coastguard Worker             mGLConsumer.clear();
455*38e8c45fSAndroid Build Coastguard Worker             mSurfaceControl.clear();
456*38e8c45fSAndroid Build Coastguard Worker             mGLHelper->tearDown();
457*38e8c45fSAndroid Build Coastguard Worker             delete mGLHelper;
458*38e8c45fSAndroid Build Coastguard Worker             mGLHelper = nullptr;
459*38e8c45fSAndroid Build Coastguard Worker         }
460*38e8c45fSAndroid Build Coastguard Worker     }
461*38e8c45fSAndroid Build Coastguard Worker 
run(uint32_t warmUpFrames,uint32_t totalFrames)462*38e8c45fSAndroid Build Coastguard Worker     nsecs_t run(uint32_t warmUpFrames, uint32_t totalFrames) {
463*38e8c45fSAndroid Build Coastguard Worker         ATRACE_CALL();
464*38e8c45fSAndroid Build Coastguard Worker 
465*38e8c45fSAndroid Build Coastguard Worker         bool result;
466*38e8c45fSAndroid Build Coastguard Worker 
467*38e8c45fSAndroid Build Coastguard Worker         resetColorGenerator();
468*38e8c45fSAndroid Build Coastguard Worker 
469*38e8c45fSAndroid Build Coastguard Worker         // Do the warm-up frames.
470*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < warmUpFrames; i++) {
471*38e8c45fSAndroid Build Coastguard Worker             result = doFrame(mSurface);
472*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
473*38e8c45fSAndroid Build Coastguard Worker                 return -1;
474*38e8c45fSAndroid Build Coastguard Worker             }
475*38e8c45fSAndroid Build Coastguard Worker         }
476*38e8c45fSAndroid Build Coastguard Worker 
477*38e8c45fSAndroid Build Coastguard Worker         // Grab the fence for the start timestamp.
478*38e8c45fSAndroid Build Coastguard Worker         sp<Fence> startFence = mGLConsumer->getCurrentFence();
479*38e8c45fSAndroid Build Coastguard Worker 
480*38e8c45fSAndroid Build Coastguard Worker         //  the timed frames.
481*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = warmUpFrames; i < totalFrames; i++) {
482*38e8c45fSAndroid Build Coastguard Worker             result = doFrame(mSurface);
483*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
484*38e8c45fSAndroid Build Coastguard Worker                 return -1;
485*38e8c45fSAndroid Build Coastguard Worker             }
486*38e8c45fSAndroid Build Coastguard Worker         }
487*38e8c45fSAndroid Build Coastguard Worker 
488*38e8c45fSAndroid Build Coastguard Worker         // Grab the fence for the end timestamp.
489*38e8c45fSAndroid Build Coastguard Worker         sp<Fence> endFence = mGLConsumer->getCurrentFence();
490*38e8c45fSAndroid Build Coastguard Worker 
491*38e8c45fSAndroid Build Coastguard Worker         // Keep doing frames until the end fence has signaled.
492*38e8c45fSAndroid Build Coastguard Worker         while (endFence->wait(0) == -ETIME) {
493*38e8c45fSAndroid Build Coastguard Worker             result = doFrame(mSurface);
494*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
495*38e8c45fSAndroid Build Coastguard Worker                 return -1;
496*38e8c45fSAndroid Build Coastguard Worker             }
497*38e8c45fSAndroid Build Coastguard Worker         }
498*38e8c45fSAndroid Build Coastguard Worker 
499*38e8c45fSAndroid Build Coastguard Worker         // Compute the time delta.
500*38e8c45fSAndroid Build Coastguard Worker         nsecs_t startTime = startFence->getSignalTime();
501*38e8c45fSAndroid Build Coastguard Worker         nsecs_t endTime = endFence->getSignalTime();
502*38e8c45fSAndroid Build Coastguard Worker 
503*38e8c45fSAndroid Build Coastguard Worker         return endTime - startTime;
504*38e8c45fSAndroid Build Coastguard Worker     }
505*38e8c45fSAndroid Build Coastguard Worker 
506*38e8c45fSAndroid Build Coastguard Worker private:
507*38e8c45fSAndroid Build Coastguard Worker 
doFrame(EGLSurface surface)508*38e8c45fSAndroid Build Coastguard Worker     bool doFrame(EGLSurface surface) {
509*38e8c45fSAndroid Build Coastguard Worker         bool result;
510*38e8c45fSAndroid Build Coastguard Worker         status_t err;
511*38e8c45fSAndroid Build Coastguard Worker 
512*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNumLayers; i++) {
513*38e8c45fSAndroid Build Coastguard Worker             result = mLayers[i].render();
514*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
515*38e8c45fSAndroid Build Coastguard Worker                 return false;
516*38e8c45fSAndroid Build Coastguard Worker             }
517*38e8c45fSAndroid Build Coastguard Worker         }
518*38e8c45fSAndroid Build Coastguard Worker 
519*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNumLayers; i++) {
520*38e8c45fSAndroid Build Coastguard Worker             result = mLayers[i].prepareComposition();
521*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
522*38e8c45fSAndroid Build Coastguard Worker                 return false;
523*38e8c45fSAndroid Build Coastguard Worker             }
524*38e8c45fSAndroid Build Coastguard Worker         }
525*38e8c45fSAndroid Build Coastguard Worker 
526*38e8c45fSAndroid Build Coastguard Worker         result = mGLHelper->makeCurrent(surface);
527*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
528*38e8c45fSAndroid Build Coastguard Worker             return false;
529*38e8c45fSAndroid Build Coastguard Worker         }
530*38e8c45fSAndroid Build Coastguard Worker 
531*38e8c45fSAndroid Build Coastguard Worker         glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
532*38e8c45fSAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
533*38e8c45fSAndroid Build Coastguard Worker 
534*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < mNumLayers; i++) {
535*38e8c45fSAndroid Build Coastguard Worker             result = mLayers[i].compose();
536*38e8c45fSAndroid Build Coastguard Worker             if (!result) {
537*38e8c45fSAndroid Build Coastguard Worker                 return false;
538*38e8c45fSAndroid Build Coastguard Worker             }
539*38e8c45fSAndroid Build Coastguard Worker         }
540*38e8c45fSAndroid Build Coastguard Worker 
541*38e8c45fSAndroid Build Coastguard Worker         result = mGLHelper->swapBuffers(surface);
542*38e8c45fSAndroid Build Coastguard Worker         if (!result) {
543*38e8c45fSAndroid Build Coastguard Worker             return false;
544*38e8c45fSAndroid Build Coastguard Worker         }
545*38e8c45fSAndroid Build Coastguard Worker 
546*38e8c45fSAndroid Build Coastguard Worker         err = mGLConsumer->updateTexImage();
547*38e8c45fSAndroid Build Coastguard Worker         if (err < 0) {
548*38e8c45fSAndroid Build Coastguard Worker             fprintf(stderr, "GLConsumer::updateTexImage error: %d\n", err);
549*38e8c45fSAndroid Build Coastguard Worker             return false;
550*38e8c45fSAndroid Build Coastguard Worker         }
551*38e8c45fSAndroid Build Coastguard Worker 
552*38e8c45fSAndroid Build Coastguard Worker         return true;
553*38e8c45fSAndroid Build Coastguard Worker     }
554*38e8c45fSAndroid Build Coastguard Worker 
countLayers(const BenchmarkDesc & desc)555*38e8c45fSAndroid Build Coastguard Worker     static size_t countLayers(const BenchmarkDesc& desc) {
556*38e8c45fSAndroid Build Coastguard Worker         size_t i;
557*38e8c45fSAndroid Build Coastguard Worker         for (i = 0; i < MAX_NUM_LAYERS; i++) {
558*38e8c45fSAndroid Build Coastguard Worker             if (desc.layers[i].rendererFactory == nullptr) {
559*38e8c45fSAndroid Build Coastguard Worker                 break;
560*38e8c45fSAndroid Build Coastguard Worker             }
561*38e8c45fSAndroid Build Coastguard Worker         }
562*38e8c45fSAndroid Build Coastguard Worker         return i;
563*38e8c45fSAndroid Build Coastguard Worker     }
564*38e8c45fSAndroid Build Coastguard Worker 
565*38e8c45fSAndroid Build Coastguard Worker     const BenchmarkDesc& mDesc;
566*38e8c45fSAndroid Build Coastguard Worker     const size_t mInstance;
567*38e8c45fSAndroid Build Coastguard Worker     const size_t mNumLayers;
568*38e8c45fSAndroid Build Coastguard Worker 
569*38e8c45fSAndroid Build Coastguard Worker     GLHelper* mGLHelper;
570*38e8c45fSAndroid Build Coastguard Worker 
571*38e8c45fSAndroid Build Coastguard Worker     // The surface into which layers are composited
572*38e8c45fSAndroid Build Coastguard Worker     sp<GLConsumer> mGLConsumer;
573*38e8c45fSAndroid Build Coastguard Worker     EGLSurface mSurface;
574*38e8c45fSAndroid Build Coastguard Worker 
575*38e8c45fSAndroid Build Coastguard Worker     // Used for displaying the surface to a window.
576*38e8c45fSAndroid Build Coastguard Worker     EGLSurface mWindowSurface;
577*38e8c45fSAndroid Build Coastguard Worker     sp<SurfaceControl> mSurfaceControl;
578*38e8c45fSAndroid Build Coastguard Worker 
579*38e8c45fSAndroid Build Coastguard Worker     Layer mLayers[MAX_NUM_LAYERS];
580*38e8c45fSAndroid Build Coastguard Worker };
581*38e8c45fSAndroid Build Coastguard Worker 
cmpDouble(const double * lhs,const double * rhs)582*38e8c45fSAndroid Build Coastguard Worker static int cmpDouble(const double* lhs, const double* rhs) {
583*38e8c45fSAndroid Build Coastguard Worker     if (*lhs < *rhs) {
584*38e8c45fSAndroid Build Coastguard Worker         return -1;
585*38e8c45fSAndroid Build Coastguard Worker     } else if (*rhs < *lhs) {
586*38e8c45fSAndroid Build Coastguard Worker         return 1;
587*38e8c45fSAndroid Build Coastguard Worker     }
588*38e8c45fSAndroid Build Coastguard Worker     return 0;
589*38e8c45fSAndroid Build Coastguard Worker }
590*38e8c45fSAndroid Build Coastguard Worker 
591*38e8c45fSAndroid Build Coastguard Worker // Run a single benchmark and print the result.
runTest(const BenchmarkDesc b,size_t run)592*38e8c45fSAndroid Build Coastguard Worker static bool runTest(const BenchmarkDesc b, size_t run) {
593*38e8c45fSAndroid Build Coastguard Worker     bool success = true;
594*38e8c45fSAndroid Build Coastguard Worker     double prevResult = 0.0, result = 0.0;
595*38e8c45fSAndroid Build Coastguard Worker     Vector<double> samples;
596*38e8c45fSAndroid Build Coastguard Worker 
597*38e8c45fSAndroid Build Coastguard Worker     uint32_t runHeight = b.runHeights[run];
598*38e8c45fSAndroid Build Coastguard Worker     uint32_t runWidth = b.width * runHeight / b.height;
599*38e8c45fSAndroid Build Coastguard Worker     printf(" %-*s | %4d x %4d | ", static_cast<int>(g_BenchmarkNameLen), b.name,
600*38e8c45fSAndroid Build Coastguard Worker             runWidth, runHeight);
601*38e8c45fSAndroid Build Coastguard Worker     fflush(stdout);
602*38e8c45fSAndroid Build Coastguard Worker 
603*38e8c45fSAndroid Build Coastguard Worker     BenchmarkRunner r(b, run);
604*38e8c45fSAndroid Build Coastguard Worker     if (!r.setUp()) {
605*38e8c45fSAndroid Build Coastguard Worker         fprintf(stderr, "error initializing runner.\n");
606*38e8c45fSAndroid Build Coastguard Worker         return false;
607*38e8c45fSAndroid Build Coastguard Worker     }
608*38e8c45fSAndroid Build Coastguard Worker 
609*38e8c45fSAndroid Build Coastguard Worker     // The slowest 1/outlierFraction sample results are ignored as potential
610*38e8c45fSAndroid Build Coastguard Worker     // outliers.
611*38e8c45fSAndroid Build Coastguard Worker     const uint32_t outlierFraction = 16;
612*38e8c45fSAndroid Build Coastguard Worker     const double threshold = .0025;
613*38e8c45fSAndroid Build Coastguard Worker 
614*38e8c45fSAndroid Build Coastguard Worker     uint32_t warmUpFrames = 1;
615*38e8c45fSAndroid Build Coastguard Worker     uint32_t totalFrames = 5;
616*38e8c45fSAndroid Build Coastguard Worker 
617*38e8c45fSAndroid Build Coastguard Worker     // Find the number of frames needed to run for over 100ms.
618*38e8c45fSAndroid Build Coastguard Worker     double runTime = 0.0;
619*38e8c45fSAndroid Build Coastguard Worker     while (true) {
620*38e8c45fSAndroid Build Coastguard Worker         runTime = double(r.run(warmUpFrames, totalFrames));
621*38e8c45fSAndroid Build Coastguard Worker         if (runTime < 50e6) {
622*38e8c45fSAndroid Build Coastguard Worker             warmUpFrames *= 2;
623*38e8c45fSAndroid Build Coastguard Worker             totalFrames *= 2;
624*38e8c45fSAndroid Build Coastguard Worker         } else {
625*38e8c45fSAndroid Build Coastguard Worker             break;
626*38e8c45fSAndroid Build Coastguard Worker         }
627*38e8c45fSAndroid Build Coastguard Worker     }
628*38e8c45fSAndroid Build Coastguard Worker 
629*38e8c45fSAndroid Build Coastguard Worker 
630*38e8c45fSAndroid Build Coastguard Worker     if (totalFrames - warmUpFrames > 16) {
631*38e8c45fSAndroid Build Coastguard Worker         // The test runs too fast to get a stable result.  Skip it.
632*38e8c45fSAndroid Build Coastguard Worker         printf("  fast");
633*38e8c45fSAndroid Build Coastguard Worker         goto done;
634*38e8c45fSAndroid Build Coastguard Worker     } else if (totalFrames == 5 && runTime > 200e6) {
635*38e8c45fSAndroid Build Coastguard Worker         // The test runs too slow to be very useful.  Skip it.
636*38e8c45fSAndroid Build Coastguard Worker         printf("  slow");
637*38e8c45fSAndroid Build Coastguard Worker         goto done;
638*38e8c45fSAndroid Build Coastguard Worker     }
639*38e8c45fSAndroid Build Coastguard Worker 
640*38e8c45fSAndroid Build Coastguard Worker     do {
641*38e8c45fSAndroid Build Coastguard Worker         size_t newSamples = samples.size();
642*38e8c45fSAndroid Build Coastguard Worker         if (newSamples == 0) {
643*38e8c45fSAndroid Build Coastguard Worker             newSamples = 4*outlierFraction;
644*38e8c45fSAndroid Build Coastguard Worker         }
645*38e8c45fSAndroid Build Coastguard Worker 
646*38e8c45fSAndroid Build Coastguard Worker         if (newSamples > 512) {
647*38e8c45fSAndroid Build Coastguard Worker             printf("varies");
648*38e8c45fSAndroid Build Coastguard Worker             goto done;
649*38e8c45fSAndroid Build Coastguard Worker         }
650*38e8c45fSAndroid Build Coastguard Worker 
651*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < newSamples; i++) {
652*38e8c45fSAndroid Build Coastguard Worker             double sample = double(r.run(warmUpFrames, totalFrames));
653*38e8c45fSAndroid Build Coastguard Worker 
654*38e8c45fSAndroid Build Coastguard Worker             if (g_SleepBetweenSamplesMs > 0) {
655*38e8c45fSAndroid Build Coastguard Worker                 usleep(g_SleepBetweenSamplesMs  * 1000);
656*38e8c45fSAndroid Build Coastguard Worker             }
657*38e8c45fSAndroid Build Coastguard Worker 
658*38e8c45fSAndroid Build Coastguard Worker             if (sample < 0.0) {
659*38e8c45fSAndroid Build Coastguard Worker                 success = false;
660*38e8c45fSAndroid Build Coastguard Worker                 goto done;
661*38e8c45fSAndroid Build Coastguard Worker             }
662*38e8c45fSAndroid Build Coastguard Worker 
663*38e8c45fSAndroid Build Coastguard Worker             samples.add(sample);
664*38e8c45fSAndroid Build Coastguard Worker         }
665*38e8c45fSAndroid Build Coastguard Worker 
666*38e8c45fSAndroid Build Coastguard Worker         samples.sort(cmpDouble);
667*38e8c45fSAndroid Build Coastguard Worker 
668*38e8c45fSAndroid Build Coastguard Worker         prevResult = result;
669*38e8c45fSAndroid Build Coastguard Worker         size_t elem = (samples.size() * (outlierFraction-1) / outlierFraction);
670*38e8c45fSAndroid Build Coastguard Worker         result = (samples[elem-1] + samples[elem]) * 0.5;
671*38e8c45fSAndroid Build Coastguard Worker     } while (fabs(result - prevResult) > threshold * result);
672*38e8c45fSAndroid Build Coastguard Worker 
673*38e8c45fSAndroid Build Coastguard Worker     printf("%6.3f", result / double(totalFrames - warmUpFrames) / 1e6);
674*38e8c45fSAndroid Build Coastguard Worker 
675*38e8c45fSAndroid Build Coastguard Worker done:
676*38e8c45fSAndroid Build Coastguard Worker 
677*38e8c45fSAndroid Build Coastguard Worker     printf("\n");
678*38e8c45fSAndroid Build Coastguard Worker     fflush(stdout);
679*38e8c45fSAndroid Build Coastguard Worker     r.tearDown();
680*38e8c45fSAndroid Build Coastguard Worker 
681*38e8c45fSAndroid Build Coastguard Worker     return success;
682*38e8c45fSAndroid Build Coastguard Worker }
683*38e8c45fSAndroid Build Coastguard Worker 
printResultsTableHeader()684*38e8c45fSAndroid Build Coastguard Worker static void printResultsTableHeader() {
685*38e8c45fSAndroid Build Coastguard Worker     const char* scenario = "Scenario";
686*38e8c45fSAndroid Build Coastguard Worker     size_t len = strlen(scenario);
687*38e8c45fSAndroid Build Coastguard Worker     size_t leftPad = (g_BenchmarkNameLen - len) / 2;
688*38e8c45fSAndroid Build Coastguard Worker     size_t rightPad = g_BenchmarkNameLen - len - leftPad;
689*38e8c45fSAndroid Build Coastguard Worker     printf(" %*s%s%*s | Resolution  | Time (ms)\n",
690*38e8c45fSAndroid Build Coastguard Worker             static_cast<int>(leftPad), "",
691*38e8c45fSAndroid Build Coastguard Worker             "Scenario", static_cast<int>(rightPad), "");
692*38e8c45fSAndroid Build Coastguard Worker }
693*38e8c45fSAndroid Build Coastguard Worker 
694*38e8c45fSAndroid Build Coastguard Worker // Run ALL the benchmarks!
runTests()695*38e8c45fSAndroid Build Coastguard Worker static bool runTests() {
696*38e8c45fSAndroid Build Coastguard Worker     printResultsTableHeader();
697*38e8c45fSAndroid Build Coastguard Worker 
698*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < NELEMS(benchmarks); i++) {
699*38e8c45fSAndroid Build Coastguard Worker         const BenchmarkDesc& b = benchmarks[i];
700*38e8c45fSAndroid Build Coastguard Worker         for (size_t j = 0; j < MAX_TEST_RUNS && b.runHeights[j]; j++) {
701*38e8c45fSAndroid Build Coastguard Worker             if (!runTest(b, j)) {
702*38e8c45fSAndroid Build Coastguard Worker                 return false;
703*38e8c45fSAndroid Build Coastguard Worker             }
704*38e8c45fSAndroid Build Coastguard Worker         }
705*38e8c45fSAndroid Build Coastguard Worker     }
706*38e8c45fSAndroid Build Coastguard Worker     return true;
707*38e8c45fSAndroid Build Coastguard Worker }
708*38e8c45fSAndroid Build Coastguard Worker 
709*38e8c45fSAndroid Build Coastguard Worker // Return the length longest benchmark name.
maxBenchmarkNameLen()710*38e8c45fSAndroid Build Coastguard Worker static size_t maxBenchmarkNameLen() {
711*38e8c45fSAndroid Build Coastguard Worker     size_t maxLen = 0;
712*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < NELEMS(benchmarks); i++) {
713*38e8c45fSAndroid Build Coastguard Worker         const BenchmarkDesc& b = benchmarks[i];
714*38e8c45fSAndroid Build Coastguard Worker         size_t len = strlen(b.name);
715*38e8c45fSAndroid Build Coastguard Worker         if (len > maxLen) {
716*38e8c45fSAndroid Build Coastguard Worker             maxLen = len;
717*38e8c45fSAndroid Build Coastguard Worker         }
718*38e8c45fSAndroid Build Coastguard Worker     }
719*38e8c45fSAndroid Build Coastguard Worker     return maxLen;
720*38e8c45fSAndroid Build Coastguard Worker }
721*38e8c45fSAndroid Build Coastguard Worker 
722*38e8c45fSAndroid Build Coastguard Worker // Print the command usage help to stderr.
showHelp(const char * cmd)723*38e8c45fSAndroid Build Coastguard Worker static void showHelp(const char* cmd) {
724*38e8c45fSAndroid Build Coastguard Worker   fprintf(stderr, "usage: %s [options]\n", cmd);
725*38e8c45fSAndroid Build Coastguard Worker   fprintf(
726*38e8c45fSAndroid Build Coastguard Worker       stderr,
727*38e8c45fSAndroid Build Coastguard Worker       "options include:\n"
728*38e8c45fSAndroid Build Coastguard Worker       "  -s N            sleep for N ms between samples\n"
729*38e8c45fSAndroid Build Coastguard Worker       "  -d              display the test frame to a window\n"
730*38e8c45fSAndroid Build Coastguard Worker       "  -i display-id   specify a display ID to use for multi-display device\n"
731*38e8c45fSAndroid Build Coastguard Worker       "                  see \"dumpsys SurfaceFlinger --display-id\" for valid "
732*38e8c45fSAndroid Build Coastguard Worker       "display IDs\n"
733*38e8c45fSAndroid Build Coastguard Worker       "  --help          print this helpful message and exit\n");
734*38e8c45fSAndroid Build Coastguard Worker }
735*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)736*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char** argv) {
737*38e8c45fSAndroid Build Coastguard Worker     if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
738*38e8c45fSAndroid Build Coastguard Worker         showHelp(argv[0]);
739*38e8c45fSAndroid Build Coastguard Worker         exit(0);
740*38e8c45fSAndroid Build Coastguard Worker     }
741*38e8c45fSAndroid Build Coastguard Worker 
742*38e8c45fSAndroid Build Coastguard Worker     const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
743*38e8c45fSAndroid Build Coastguard Worker     if (ids.empty()) {
744*38e8c45fSAndroid Build Coastguard Worker         fprintf(stderr, "Failed to get ID for any displays.\n");
745*38e8c45fSAndroid Build Coastguard Worker         exit(3);
746*38e8c45fSAndroid Build Coastguard Worker     }
747*38e8c45fSAndroid Build Coastguard Worker 
748*38e8c45fSAndroid Build Coastguard Worker     std::optional<PhysicalDisplayId> displayId;
749*38e8c45fSAndroid Build Coastguard Worker 
750*38e8c45fSAndroid Build Coastguard Worker     for (;;) {
751*38e8c45fSAndroid Build Coastguard Worker         int ret;
752*38e8c45fSAndroid Build Coastguard Worker         int option_index = 0;
753*38e8c45fSAndroid Build Coastguard Worker         static struct option long_options[] = {
754*38e8c45fSAndroid Build Coastguard Worker             {"help",     no_argument, 0,  0 },
755*38e8c45fSAndroid Build Coastguard Worker             {     0,               0, 0,  0 }
756*38e8c45fSAndroid Build Coastguard Worker         };
757*38e8c45fSAndroid Build Coastguard Worker 
758*38e8c45fSAndroid Build Coastguard Worker         ret = getopt_long(argc, argv, "ds:i:",
759*38e8c45fSAndroid Build Coastguard Worker                           long_options, &option_index);
760*38e8c45fSAndroid Build Coastguard Worker 
761*38e8c45fSAndroid Build Coastguard Worker         if (ret < 0) {
762*38e8c45fSAndroid Build Coastguard Worker             break;
763*38e8c45fSAndroid Build Coastguard Worker         }
764*38e8c45fSAndroid Build Coastguard Worker 
765*38e8c45fSAndroid Build Coastguard Worker         switch(ret) {
766*38e8c45fSAndroid Build Coastguard Worker             case 'd':
767*38e8c45fSAndroid Build Coastguard Worker                 g_PresentToWindow = true;
768*38e8c45fSAndroid Build Coastguard Worker             break;
769*38e8c45fSAndroid Build Coastguard Worker 
770*38e8c45fSAndroid Build Coastguard Worker             case 's':
771*38e8c45fSAndroid Build Coastguard Worker                 g_SleepBetweenSamplesMs = atoi(optarg);
772*38e8c45fSAndroid Build Coastguard Worker             break;
773*38e8c45fSAndroid Build Coastguard Worker 
774*38e8c45fSAndroid Build Coastguard Worker             case 'i':
775*38e8c45fSAndroid Build Coastguard Worker                 displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
776*38e8c45fSAndroid Build Coastguard Worker                 if (!displayId) {
777*38e8c45fSAndroid Build Coastguard Worker                     fprintf(stderr, "Invalid display ID: %s.\n", optarg);
778*38e8c45fSAndroid Build Coastguard Worker                     exit(4);
779*38e8c45fSAndroid Build Coastguard Worker                 }
780*38e8c45fSAndroid Build Coastguard Worker             break;
781*38e8c45fSAndroid Build Coastguard Worker 
782*38e8c45fSAndroid Build Coastguard Worker             case 0:
783*38e8c45fSAndroid Build Coastguard Worker                 if (strcmp(long_options[option_index].name, "help")) {
784*38e8c45fSAndroid Build Coastguard Worker                     showHelp(argv[0]);
785*38e8c45fSAndroid Build Coastguard Worker                     exit(0);
786*38e8c45fSAndroid Build Coastguard Worker                 }
787*38e8c45fSAndroid Build Coastguard Worker             break;
788*38e8c45fSAndroid Build Coastguard Worker 
789*38e8c45fSAndroid Build Coastguard Worker             default:
790*38e8c45fSAndroid Build Coastguard Worker                 showHelp(argv[0]);
791*38e8c45fSAndroid Build Coastguard Worker                 exit(2);
792*38e8c45fSAndroid Build Coastguard Worker         }
793*38e8c45fSAndroid Build Coastguard Worker     }
794*38e8c45fSAndroid Build Coastguard Worker 
795*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) { // no display id is specified
796*38e8c45fSAndroid Build Coastguard Worker         if (ids.size() == 1) {
797*38e8c45fSAndroid Build Coastguard Worker             displayId = ids.front();
798*38e8c45fSAndroid Build Coastguard Worker         } else {
799*38e8c45fSAndroid Build Coastguard Worker             fprintf(stderr, "Please specify a display ID for multi-display device.\n");
800*38e8c45fSAndroid Build Coastguard Worker             showHelp(argv[0]);
801*38e8c45fSAndroid Build Coastguard Worker             exit(5);
802*38e8c45fSAndroid Build Coastguard Worker         }
803*38e8c45fSAndroid Build Coastguard Worker     }
804*38e8c45fSAndroid Build Coastguard Worker 
805*38e8c45fSAndroid Build Coastguard Worker     g_DisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
806*38e8c45fSAndroid Build Coastguard Worker     if (g_DisplayToken == nullptr) {
807*38e8c45fSAndroid Build Coastguard Worker         fprintf(stderr, "SurfaceComposer::getPhysicalDisplayToken failed.\n");
808*38e8c45fSAndroid Build Coastguard Worker         exit(6);
809*38e8c45fSAndroid Build Coastguard Worker     }
810*38e8c45fSAndroid Build Coastguard Worker 
811*38e8c45fSAndroid Build Coastguard Worker     g_BenchmarkNameLen = maxBenchmarkNameLen();
812*38e8c45fSAndroid Build Coastguard Worker 
813*38e8c45fSAndroid Build Coastguard Worker     printf(" cmdline:");
814*38e8c45fSAndroid Build Coastguard Worker     for (int i = 0; i < argc; i++) {
815*38e8c45fSAndroid Build Coastguard Worker         printf(" %s", argv[i]);
816*38e8c45fSAndroid Build Coastguard Worker     }
817*38e8c45fSAndroid Build Coastguard Worker     printf("\n");
818*38e8c45fSAndroid Build Coastguard Worker 
819*38e8c45fSAndroid Build Coastguard Worker     if (!runTests()) {
820*38e8c45fSAndroid Build Coastguard Worker         fprintf(stderr, "exiting due to error.\n");
821*38e8c45fSAndroid Build Coastguard Worker         return 1;
822*38e8c45fSAndroid Build Coastguard Worker     }
823*38e8c45fSAndroid Build Coastguard Worker 
824*38e8c45fSAndroid Build Coastguard Worker     return 0;
825*38e8c45fSAndroid Build Coastguard Worker }
826