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