xref: /aosp_15_r20/frameworks/native/opengl/tests/hwc/hwcStress.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2010 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 
18*38e8c45fSAndroid Build Coastguard Worker /*
19*38e8c45fSAndroid Build Coastguard Worker  * Hardware Composer stress test
20*38e8c45fSAndroid Build Coastguard Worker  *
21*38e8c45fSAndroid Build Coastguard Worker  * Performs a pseudo-random (prandom) sequence of operations to the
22*38e8c45fSAndroid Build Coastguard Worker  * Hardware Composer (HWC), for a specified number of passes or for
23*38e8c45fSAndroid Build Coastguard Worker  * a specified period of time.  By default the period of time is FLT_MAX,
24*38e8c45fSAndroid Build Coastguard Worker  * so that the number of passes will take precedence.
25*38e8c45fSAndroid Build Coastguard Worker  *
26*38e8c45fSAndroid Build Coastguard Worker  * The passes are grouped together, where (pass / passesPerGroup) specifies
27*38e8c45fSAndroid Build Coastguard Worker  * which group a particular pass is in.  This causes every passesPerGroup
28*38e8c45fSAndroid Build Coastguard Worker  * worth of sequential passes to be within the same group.  Computationally
29*38e8c45fSAndroid Build Coastguard Worker  * intensive operations are performed just once at the beginning of a group
30*38e8c45fSAndroid Build Coastguard Worker  * of passes and then used by all the passes in that group.  This is done
31*38e8c45fSAndroid Build Coastguard Worker  * so as to increase both the average and peak rate of graphic operations,
32*38e8c45fSAndroid Build Coastguard Worker  * by moving computationally intensive operations to the beginning of a group.
33*38e8c45fSAndroid Build Coastguard Worker  * In particular, at the start of each group of passes a set of
34*38e8c45fSAndroid Build Coastguard Worker  * graphic buffers are created, then used by the first and remaining
35*38e8c45fSAndroid Build Coastguard Worker  * passes of that group of passes.
36*38e8c45fSAndroid Build Coastguard Worker  *
37*38e8c45fSAndroid Build Coastguard Worker  * The per-group initialization of the graphic buffers is performed
38*38e8c45fSAndroid Build Coastguard Worker  * by a function called initFrames.  This function creates an array
39*38e8c45fSAndroid Build Coastguard Worker  * of smart pointers to the graphic buffers, in the form of a vector
40*38e8c45fSAndroid Build Coastguard Worker  * of vectors.  The array is accessed in row major order, so each
41*38e8c45fSAndroid Build Coastguard Worker  * row is a vector of smart pointers.  All the pointers of a single
42*38e8c45fSAndroid Build Coastguard Worker  * row point to graphic buffers which use the same pixel format and
43*38e8c45fSAndroid Build Coastguard Worker  * have the same dimension, although it is likely that each one is
44*38e8c45fSAndroid Build Coastguard Worker  * filled with a different color.  This is done so that after doing
45*38e8c45fSAndroid Build Coastguard Worker  * the first HWC prepare then set call, subsequent set calls can
46*38e8c45fSAndroid Build Coastguard Worker  * be made with each of the layer handles changed to a different
47*38e8c45fSAndroid Build Coastguard Worker  * graphic buffer within the same row.  Since the graphic buffers
48*38e8c45fSAndroid Build Coastguard Worker  * in a particular row have the same pixel format and dimension,
49*38e8c45fSAndroid Build Coastguard Worker  * additional HWC set calls can be made, without having to perform
50*38e8c45fSAndroid Build Coastguard Worker  * an HWC prepare call.
51*38e8c45fSAndroid Build Coastguard Worker  *
52*38e8c45fSAndroid Build Coastguard Worker  * This test supports the following command-line options:
53*38e8c45fSAndroid Build Coastguard Worker  *
54*38e8c45fSAndroid Build Coastguard Worker  *   -v        Verbose
55*38e8c45fSAndroid Build Coastguard Worker  *   -s num    Starting pass
56*38e8c45fSAndroid Build Coastguard Worker  *   -e num    Ending pass
57*38e8c45fSAndroid Build Coastguard Worker  *   -p num    Execute the single pass specified by num
58*38e8c45fSAndroid Build Coastguard Worker  *   -n num    Number of set operations to perform after each prepare operation
59*38e8c45fSAndroid Build Coastguard Worker  *   -t float  Maximum time in seconds to execute the test
60*38e8c45fSAndroid Build Coastguard Worker  *   -d float  Delay in seconds performed after each set operation
61*38e8c45fSAndroid Build Coastguard Worker  *   -D float  Delay in seconds performed after the last pass is executed
62*38e8c45fSAndroid Build Coastguard Worker  *
63*38e8c45fSAndroid Build Coastguard Worker  * Typically the test is executed for a large range of passes.  By default
64*38e8c45fSAndroid Build Coastguard Worker  * passes 0 through 99999 (100,000 passes) are executed.  Although this test
65*38e8c45fSAndroid Build Coastguard Worker  * does not validate the generated image, at times it is useful to reexecute
66*38e8c45fSAndroid Build Coastguard Worker  * a particular pass and leave the displayed image on the screen for an
67*38e8c45fSAndroid Build Coastguard Worker  * extended period of time.  This can be done either by setting the -s
68*38e8c45fSAndroid Build Coastguard Worker  * and -e options to the desired pass, along with a large value for -D.
69*38e8c45fSAndroid Build Coastguard Worker  * This can also be done via the -p option, again with a large value for
70*38e8c45fSAndroid Build Coastguard Worker  * the -D options.
71*38e8c45fSAndroid Build Coastguard Worker  *
72*38e8c45fSAndroid Build Coastguard Worker  * So far this test only contains code to create graphic buffers with
73*38e8c45fSAndroid Build Coastguard Worker  * a continuous solid color.  Although this test is unable to validate the
74*38e8c45fSAndroid Build Coastguard Worker  * image produced, any image that contains other than rectangles of a solid
75*38e8c45fSAndroid Build Coastguard Worker  * color are incorrect.  Note that the rectangles may use a transparent
76*38e8c45fSAndroid Build Coastguard Worker  * color and have a blending operation that causes the color in overlapping
77*38e8c45fSAndroid Build Coastguard Worker  * rectangles to be mixed.  In such cases the overlapping portions may have
78*38e8c45fSAndroid Build Coastguard Worker  * a different color from the rest of the rectangle.
79*38e8c45fSAndroid Build Coastguard Worker  */
80*38e8c45fSAndroid Build Coastguard Worker 
81*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "hwcStressTest"
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
84*38e8c45fSAndroid Build Coastguard Worker #include <assert.h>
85*38e8c45fSAndroid Build Coastguard Worker #include <cerrno>
86*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
87*38e8c45fSAndroid Build Coastguard Worker #include <cstdlib>
88*38e8c45fSAndroid Build Coastguard Worker #include <ctime>
89*38e8c45fSAndroid Build Coastguard Worker #include <libgen.h>
90*38e8c45fSAndroid Build Coastguard Worker #include <sched.h>
91*38e8c45fSAndroid Build Coastguard Worker #include <sstream>
92*38e8c45fSAndroid Build Coastguard Worker #include <stdint.h>
93*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
94*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
95*38e8c45fSAndroid Build Coastguard Worker #include <vector>
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker #include <sys/syscall.h>
98*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
99*38e8c45fSAndroid Build Coastguard Worker #include <sys/wait.h>
100*38e8c45fSAndroid Build Coastguard Worker 
101*38e8c45fSAndroid Build Coastguard Worker #include <EGL/egl.h>
102*38e8c45fSAndroid Build Coastguard Worker #include <EGL/eglext.h>
103*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
104*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2ext.h>
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
109*38e8c45fSAndroid Build Coastguard Worker #include <testUtil.h>
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker #include <hardware/hwcomposer.h>
112*38e8c45fSAndroid Build Coastguard Worker 
113*38e8c45fSAndroid Build Coastguard Worker #include <glTestLib.h>
114*38e8c45fSAndroid Build Coastguard Worker #include "hwcTestLib.h"
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker using namespace std;
117*38e8c45fSAndroid Build Coastguard Worker using namespace android;
118*38e8c45fSAndroid Build Coastguard Worker 
119*38e8c45fSAndroid Build Coastguard Worker const float maxSizeRatio = 1.3;  // Graphic buffers can be upto this munch
120*38e8c45fSAndroid Build Coastguard Worker                                  // larger than the default screen size
121*38e8c45fSAndroid Build Coastguard Worker const unsigned int passesPerGroup = 10; // A group of passes all use the same
122*38e8c45fSAndroid Build Coastguard Worker                                         // graphic buffers
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker // Ratios at which rare and frequent conditions should be produced
125*38e8c45fSAndroid Build Coastguard Worker const float rareRatio = 0.1;
126*38e8c45fSAndroid Build Coastguard Worker const float freqRatio = 0.9;
127*38e8c45fSAndroid Build Coastguard Worker 
128*38e8c45fSAndroid Build Coastguard Worker // Defaults for command-line options
129*38e8c45fSAndroid Build Coastguard Worker const bool defaultVerbose = false;
130*38e8c45fSAndroid Build Coastguard Worker const unsigned int defaultStartPass = 0;
131*38e8c45fSAndroid Build Coastguard Worker const unsigned int defaultEndPass = 99999;
132*38e8c45fSAndroid Build Coastguard Worker const unsigned int defaultPerPassNumSet = 10;
133*38e8c45fSAndroid Build Coastguard Worker const float defaultPerSetDelay = 0.0; // Default delay after each set
134*38e8c45fSAndroid Build Coastguard Worker                                       // operation.  Default delay of
135*38e8c45fSAndroid Build Coastguard Worker                                       // zero used so as to perform the
136*38e8c45fSAndroid Build Coastguard Worker                                       // the set operations as quickly
137*38e8c45fSAndroid Build Coastguard Worker                                       // as possible.
138*38e8c45fSAndroid Build Coastguard Worker const float defaultEndDelay = 2.0; // Default delay between completion of
139*38e8c45fSAndroid Build Coastguard Worker                                    // final pass and restart of framework
140*38e8c45fSAndroid Build Coastguard Worker const float defaultDuration = FLT_MAX; // A fairly long time, so that
141*38e8c45fSAndroid Build Coastguard Worker                                        // range of passes will have
142*38e8c45fSAndroid Build Coastguard Worker                                        // precedence
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker // Command-line option settings
145*38e8c45fSAndroid Build Coastguard Worker static bool verbose = defaultVerbose;
146*38e8c45fSAndroid Build Coastguard Worker static unsigned int startPass = defaultStartPass;
147*38e8c45fSAndroid Build Coastguard Worker static unsigned int endPass = defaultEndPass;
148*38e8c45fSAndroid Build Coastguard Worker static unsigned int numSet = defaultPerPassNumSet;
149*38e8c45fSAndroid Build Coastguard Worker static float perSetDelay = defaultPerSetDelay;
150*38e8c45fSAndroid Build Coastguard Worker static float endDelay = defaultEndDelay;
151*38e8c45fSAndroid Build Coastguard Worker static float duration = defaultDuration;
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker // Command-line mutual exclusion detection flags.
154*38e8c45fSAndroid Build Coastguard Worker // Corresponding flag set true once an option is used.
155*38e8c45fSAndroid Build Coastguard Worker bool eFlag, sFlag, pFlag;
156*38e8c45fSAndroid Build Coastguard Worker 
157*38e8c45fSAndroid Build Coastguard Worker #define MAXSTR               100
158*38e8c45fSAndroid Build Coastguard Worker #define MAXCMD               200
159*38e8c45fSAndroid Build Coastguard Worker #define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
160*38e8c45fSAndroid Build Coastguard Worker                                  // it has been added
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker #define CMD_STOP_FRAMEWORK   "stop 2>&1"
163*38e8c45fSAndroid Build Coastguard Worker #define CMD_START_FRAMEWORK  "start 2>&1"
164*38e8c45fSAndroid Build Coastguard Worker 
165*38e8c45fSAndroid Build Coastguard Worker #define NUMA(a) (sizeof(a) / sizeof((a)[0]))
166*38e8c45fSAndroid Build Coastguard Worker #define MEMCLR(addr, size) do { \
167*38e8c45fSAndroid Build Coastguard Worker         memset((addr), 0, (size)); \
168*38e8c45fSAndroid Build Coastguard Worker     } while (0)
169*38e8c45fSAndroid Build Coastguard Worker 
170*38e8c45fSAndroid Build Coastguard Worker // File scope constants
171*38e8c45fSAndroid Build Coastguard Worker const unsigned int blendingOps[] = {
172*38e8c45fSAndroid Build Coastguard Worker     HWC_BLENDING_NONE,
173*38e8c45fSAndroid Build Coastguard Worker     HWC_BLENDING_PREMULT,
174*38e8c45fSAndroid Build Coastguard Worker     HWC_BLENDING_COVERAGE,
175*38e8c45fSAndroid Build Coastguard Worker };
176*38e8c45fSAndroid Build Coastguard Worker const unsigned int layerFlags[] = {
177*38e8c45fSAndroid Build Coastguard Worker     HWC_SKIP_LAYER,
178*38e8c45fSAndroid Build Coastguard Worker };
179*38e8c45fSAndroid Build Coastguard Worker const vector<unsigned int> vecLayerFlags(layerFlags,
180*38e8c45fSAndroid Build Coastguard Worker     layerFlags + NUMA(layerFlags));
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker const unsigned int transformFlags[] = {
183*38e8c45fSAndroid Build Coastguard Worker     HWC_TRANSFORM_FLIP_H,
184*38e8c45fSAndroid Build Coastguard Worker     HWC_TRANSFORM_FLIP_V,
185*38e8c45fSAndroid Build Coastguard Worker     HWC_TRANSFORM_ROT_90,
186*38e8c45fSAndroid Build Coastguard Worker     // ROT_180 & ROT_270 intentionally not listed, because they
187*38e8c45fSAndroid Build Coastguard Worker     // they are formed from combinations of the flags already listed.
188*38e8c45fSAndroid Build Coastguard Worker };
189*38e8c45fSAndroid Build Coastguard Worker const vector<unsigned int> vecTransformFlags(transformFlags,
190*38e8c45fSAndroid Build Coastguard Worker     transformFlags + NUMA(transformFlags));
191*38e8c45fSAndroid Build Coastguard Worker 
192*38e8c45fSAndroid Build Coastguard Worker // File scope globals
193*38e8c45fSAndroid Build Coastguard Worker static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
194*38e8c45fSAndroid Build Coastguard Worker         GraphicBuffer::USAGE_SW_WRITE_RARELY;
195*38e8c45fSAndroid Build Coastguard Worker static hwc_composer_device_1_t *hwcDevice;
196*38e8c45fSAndroid Build Coastguard Worker static EGLDisplay dpy;
197*38e8c45fSAndroid Build Coastguard Worker static EGLSurface surface;
198*38e8c45fSAndroid Build Coastguard Worker static EGLint width, height;
199*38e8c45fSAndroid Build Coastguard Worker static vector <vector <sp<GraphicBuffer> > > frames;
200*38e8c45fSAndroid Build Coastguard Worker 
201*38e8c45fSAndroid Build Coastguard Worker // File scope prototypes
202*38e8c45fSAndroid Build Coastguard Worker void init(void);
203*38e8c45fSAndroid Build Coastguard Worker void initFrames(unsigned int seed);
204*38e8c45fSAndroid Build Coastguard Worker template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num);
205*38e8c45fSAndroid Build Coastguard Worker template <class T> T vectorOr(const vector<T>& vec);
206*38e8c45fSAndroid Build Coastguard Worker 
207*38e8c45fSAndroid Build Coastguard Worker /*
208*38e8c45fSAndroid Build Coastguard Worker  * Main
209*38e8c45fSAndroid Build Coastguard Worker  *
210*38e8c45fSAndroid Build Coastguard Worker  * Performs the following high-level sequence of operations:
211*38e8c45fSAndroid Build Coastguard Worker  *
212*38e8c45fSAndroid Build Coastguard Worker  *   1. Command-line parsing
213*38e8c45fSAndroid Build Coastguard Worker  *
214*38e8c45fSAndroid Build Coastguard Worker  *   2. Initialization
215*38e8c45fSAndroid Build Coastguard Worker  *
216*38e8c45fSAndroid Build Coastguard Worker  *   3. For each pass:
217*38e8c45fSAndroid Build Coastguard Worker  *
218*38e8c45fSAndroid Build Coastguard Worker  *        a. If pass is first pass or in a different group from the
219*38e8c45fSAndroid Build Coastguard Worker  *           previous pass, initialize the array of graphic buffers.
220*38e8c45fSAndroid Build Coastguard Worker  *
221*38e8c45fSAndroid Build Coastguard Worker  *        b. Create a HWC list with room to specify a prandomly
222*38e8c45fSAndroid Build Coastguard Worker  *           selected number of layers.
223*38e8c45fSAndroid Build Coastguard Worker  *
224*38e8c45fSAndroid Build Coastguard Worker  *        c. Select a subset of the rows from the graphic buffer array,
225*38e8c45fSAndroid Build Coastguard Worker  *           such that there is a unique row to be used for each
226*38e8c45fSAndroid Build Coastguard Worker  *           of the layers in the HWC list.
227*38e8c45fSAndroid Build Coastguard Worker  *
228*38e8c45fSAndroid Build Coastguard Worker  *        d. Prandomly fill in the HWC list with handles
229*38e8c45fSAndroid Build Coastguard Worker  *           selected from any of the columns of the selected row.
230*38e8c45fSAndroid Build Coastguard Worker  *
231*38e8c45fSAndroid Build Coastguard Worker  *        e. Pass the populated list to the HWC prepare call.
232*38e8c45fSAndroid Build Coastguard Worker  *
233*38e8c45fSAndroid Build Coastguard Worker  *        f. Pass the populated list to the HWC set call.
234*38e8c45fSAndroid Build Coastguard Worker  *
235*38e8c45fSAndroid Build Coastguard Worker  *        g. If additional set calls are to be made, then for each
236*38e8c45fSAndroid Build Coastguard Worker  *           additional set call, select a new set of handles and
237*38e8c45fSAndroid Build Coastguard Worker  *           perform the set call.
238*38e8c45fSAndroid Build Coastguard Worker  */
239*38e8c45fSAndroid Build Coastguard Worker int
main(int argc,char * argv[])240*38e8c45fSAndroid Build Coastguard Worker main(int argc, char *argv[])
241*38e8c45fSAndroid Build Coastguard Worker {
242*38e8c45fSAndroid Build Coastguard Worker     int rv, opt;
243*38e8c45fSAndroid Build Coastguard Worker     char *chptr;
244*38e8c45fSAndroid Build Coastguard Worker     unsigned int pass;
245*38e8c45fSAndroid Build Coastguard Worker     char cmd[MAXCMD];
246*38e8c45fSAndroid Build Coastguard Worker     struct timeval startTime, currentTime, delta;
247*38e8c45fSAndroid Build Coastguard Worker 
248*38e8c45fSAndroid Build Coastguard Worker     testSetLogCatTag(LOG_TAG);
249*38e8c45fSAndroid Build Coastguard Worker 
250*38e8c45fSAndroid Build Coastguard Worker     // Parse command line arguments
251*38e8c45fSAndroid Build Coastguard Worker     while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) {
252*38e8c45fSAndroid Build Coastguard Worker         switch (opt) {
253*38e8c45fSAndroid Build Coastguard Worker           case 'd': // Delay after each set operation
254*38e8c45fSAndroid Build Coastguard Worker             perSetDelay = strtod(optarg, &chptr);
255*38e8c45fSAndroid Build Coastguard Worker             if ((*chptr != '\0') || (perSetDelay < 0.0)) {
256*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified per pass delay of: "
257*38e8c45fSAndroid Build Coastguard Worker                            "%s", optarg);
258*38e8c45fSAndroid Build Coastguard Worker                 exit(1);
259*38e8c45fSAndroid Build Coastguard Worker             }
260*38e8c45fSAndroid Build Coastguard Worker             break;
261*38e8c45fSAndroid Build Coastguard Worker 
262*38e8c45fSAndroid Build Coastguard Worker           case 'D': // End of test delay
263*38e8c45fSAndroid Build Coastguard Worker                     // Delay between completion of final pass and restart
264*38e8c45fSAndroid Build Coastguard Worker                     // of framework
265*38e8c45fSAndroid Build Coastguard Worker             endDelay = strtod(optarg, &chptr);
266*38e8c45fSAndroid Build Coastguard Worker             if ((*chptr != '\0') || (endDelay < 0.0)) {
267*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified end of test delay "
268*38e8c45fSAndroid Build Coastguard Worker                            "of: %s", optarg);
269*38e8c45fSAndroid Build Coastguard Worker                 exit(2);
270*38e8c45fSAndroid Build Coastguard Worker             }
271*38e8c45fSAndroid Build Coastguard Worker             break;
272*38e8c45fSAndroid Build Coastguard Worker 
273*38e8c45fSAndroid Build Coastguard Worker           case 't': // Duration
274*38e8c45fSAndroid Build Coastguard Worker             duration = strtod(optarg, &chptr);
275*38e8c45fSAndroid Build Coastguard Worker             if ((*chptr != '\0') || (duration < 0.0)) {
276*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified duration of: %s",
277*38e8c45fSAndroid Build Coastguard Worker                            optarg);
278*38e8c45fSAndroid Build Coastguard Worker                 exit(3);
279*38e8c45fSAndroid Build Coastguard Worker             }
280*38e8c45fSAndroid Build Coastguard Worker             break;
281*38e8c45fSAndroid Build Coastguard Worker 
282*38e8c45fSAndroid Build Coastguard Worker           case 'n': // Num set operations per pass
283*38e8c45fSAndroid Build Coastguard Worker             numSet = strtoul(optarg, &chptr, 10);
284*38e8c45fSAndroid Build Coastguard Worker             if (*chptr != '\0') {
285*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified num set per pass "
286*38e8c45fSAndroid Build Coastguard Worker                            "of: %s", optarg);
287*38e8c45fSAndroid Build Coastguard Worker                 exit(4);
288*38e8c45fSAndroid Build Coastguard Worker             }
289*38e8c45fSAndroid Build Coastguard Worker             break;
290*38e8c45fSAndroid Build Coastguard Worker 
291*38e8c45fSAndroid Build Coastguard Worker           case 's': // Starting Pass
292*38e8c45fSAndroid Build Coastguard Worker             sFlag = true;
293*38e8c45fSAndroid Build Coastguard Worker             if (pFlag) {
294*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid combination of command-line options.");
295*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  The -p option is mutually exclusive from the");
296*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  -s and -e options.");
297*38e8c45fSAndroid Build Coastguard Worker                 exit(5);
298*38e8c45fSAndroid Build Coastguard Worker             }
299*38e8c45fSAndroid Build Coastguard Worker             startPass = strtoul(optarg, &chptr, 10);
300*38e8c45fSAndroid Build Coastguard Worker             if (*chptr != '\0') {
301*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified starting pass "
302*38e8c45fSAndroid Build Coastguard Worker                            "of: %s", optarg);
303*38e8c45fSAndroid Build Coastguard Worker                 exit(6);
304*38e8c45fSAndroid Build Coastguard Worker             }
305*38e8c45fSAndroid Build Coastguard Worker             break;
306*38e8c45fSAndroid Build Coastguard Worker 
307*38e8c45fSAndroid Build Coastguard Worker           case 'e': // Ending Pass
308*38e8c45fSAndroid Build Coastguard Worker             eFlag = true;
309*38e8c45fSAndroid Build Coastguard Worker             if (pFlag) {
310*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid combination of command-line options.");
311*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  The -p option is mutually exclusive from the");
312*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  -s and -e options.");
313*38e8c45fSAndroid Build Coastguard Worker                 exit(7);
314*38e8c45fSAndroid Build Coastguard Worker             }
315*38e8c45fSAndroid Build Coastguard Worker             endPass = strtoul(optarg, &chptr, 10);
316*38e8c45fSAndroid Build Coastguard Worker             if (*chptr != '\0') {
317*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified ending pass "
318*38e8c45fSAndroid Build Coastguard Worker                            "of: %s", optarg);
319*38e8c45fSAndroid Build Coastguard Worker                 exit(8);
320*38e8c45fSAndroid Build Coastguard Worker             }
321*38e8c45fSAndroid Build Coastguard Worker             break;
322*38e8c45fSAndroid Build Coastguard Worker 
323*38e8c45fSAndroid Build Coastguard Worker           case 'p': // Run a single specified pass
324*38e8c45fSAndroid Build Coastguard Worker             pFlag = true;
325*38e8c45fSAndroid Build Coastguard Worker             if (sFlag || eFlag) {
326*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid combination of command-line options.");
327*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  The -p option is mutually exclusive from the");
328*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  -s and -e options.");
329*38e8c45fSAndroid Build Coastguard Worker                 exit(9);
330*38e8c45fSAndroid Build Coastguard Worker             }
331*38e8c45fSAndroid Build Coastguard Worker             startPass = endPass = strtoul(optarg, &chptr, 10);
332*38e8c45fSAndroid Build Coastguard Worker             if (*chptr != '\0') {
333*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("Invalid command-line specified pass of: %s",
334*38e8c45fSAndroid Build Coastguard Worker                            optarg);
335*38e8c45fSAndroid Build Coastguard Worker                 exit(10);
336*38e8c45fSAndroid Build Coastguard Worker             }
337*38e8c45fSAndroid Build Coastguard Worker             break;
338*38e8c45fSAndroid Build Coastguard Worker 
339*38e8c45fSAndroid Build Coastguard Worker           case 'v': // Verbose
340*38e8c45fSAndroid Build Coastguard Worker             verbose = true;
341*38e8c45fSAndroid Build Coastguard Worker             break;
342*38e8c45fSAndroid Build Coastguard Worker 
343*38e8c45fSAndroid Build Coastguard Worker           case 'h': // Help
344*38e8c45fSAndroid Build Coastguard Worker           case '?':
345*38e8c45fSAndroid Build Coastguard Worker           default:
346*38e8c45fSAndroid Build Coastguard Worker             testPrintE("  %s [options]", basename(argv[0]));
347*38e8c45fSAndroid Build Coastguard Worker             testPrintE("    options:");
348*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -p Execute specified pass");
349*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -s Starting pass");
350*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -e Ending pass");
351*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -t Duration");
352*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -d Delay after each set operation");
353*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -D End of test delay");
354*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -n Num set operations per pass");
355*38e8c45fSAndroid Build Coastguard Worker             testPrintE("      -v Verbose");
356*38e8c45fSAndroid Build Coastguard Worker             exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
357*38e8c45fSAndroid Build Coastguard Worker         }
358*38e8c45fSAndroid Build Coastguard Worker     }
359*38e8c45fSAndroid Build Coastguard Worker     if (endPass < startPass) {
360*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unexpected ending pass before starting pass");
361*38e8c45fSAndroid Build Coastguard Worker         testPrintE("  startPass: %u endPass: %u", startPass, endPass);
362*38e8c45fSAndroid Build Coastguard Worker         exit(12);
363*38e8c45fSAndroid Build Coastguard Worker     }
364*38e8c45fSAndroid Build Coastguard Worker     if (argc != optind) {
365*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unexpected command-line postional argument");
366*38e8c45fSAndroid Build Coastguard Worker         testPrintE("  %s [-s start_pass] [-e end_pass] [-t duration]",
367*38e8c45fSAndroid Build Coastguard Worker             basename(argv[0]));
368*38e8c45fSAndroid Build Coastguard Worker         exit(13);
369*38e8c45fSAndroid Build Coastguard Worker     }
370*38e8c45fSAndroid Build Coastguard Worker     testPrintI("duration: %g", duration);
371*38e8c45fSAndroid Build Coastguard Worker     testPrintI("startPass: %u", startPass);
372*38e8c45fSAndroid Build Coastguard Worker     testPrintI("endPass: %u", endPass);
373*38e8c45fSAndroid Build Coastguard Worker     testPrintI("numSet: %u", numSet);
374*38e8c45fSAndroid Build Coastguard Worker 
375*38e8c45fSAndroid Build Coastguard Worker     // Stop framework
376*38e8c45fSAndroid Build Coastguard Worker     rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
377*38e8c45fSAndroid Build Coastguard Worker     if (rv >= (signed) sizeof(cmd) - 1) {
378*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
379*38e8c45fSAndroid Build Coastguard Worker         exit(14);
380*38e8c45fSAndroid Build Coastguard Worker     }
381*38e8c45fSAndroid Build Coastguard Worker     testExecCmd(cmd);
382*38e8c45fSAndroid Build Coastguard Worker     testDelay(1.0); // TODO - need means to query whether asyncronous stop
383*38e8c45fSAndroid Build Coastguard Worker                     // framework operation has completed.  For now, just wait
384*38e8c45fSAndroid Build Coastguard Worker                     // a long time.
385*38e8c45fSAndroid Build Coastguard Worker 
386*38e8c45fSAndroid Build Coastguard Worker     init();
387*38e8c45fSAndroid Build Coastguard Worker 
388*38e8c45fSAndroid Build Coastguard Worker     // For each pass
389*38e8c45fSAndroid Build Coastguard Worker     gettimeofday(&startTime, NULL);
390*38e8c45fSAndroid Build Coastguard Worker     for (pass = startPass; pass <= endPass; pass++) {
391*38e8c45fSAndroid Build Coastguard Worker         // Stop if duration of work has already been performed
392*38e8c45fSAndroid Build Coastguard Worker         gettimeofday(&currentTime, NULL);
393*38e8c45fSAndroid Build Coastguard Worker         delta = tvDelta(&startTime, &currentTime);
394*38e8c45fSAndroid Build Coastguard Worker         if (tv2double(&delta) > duration) { break; }
395*38e8c45fSAndroid Build Coastguard Worker 
396*38e8c45fSAndroid Build Coastguard Worker         // Regenerate a new set of test frames when this pass is
397*38e8c45fSAndroid Build Coastguard Worker         // either the first pass or is in a different group then
398*38e8c45fSAndroid Build Coastguard Worker         // the previous pass.  A group of passes are passes that
399*38e8c45fSAndroid Build Coastguard Worker         // all have the same quotient when their pass number is
400*38e8c45fSAndroid Build Coastguard Worker         // divided by passesPerGroup.
401*38e8c45fSAndroid Build Coastguard Worker         if ((pass == startPass)
402*38e8c45fSAndroid Build Coastguard Worker             || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) {
403*38e8c45fSAndroid Build Coastguard Worker             initFrames(pass / passesPerGroup);
404*38e8c45fSAndroid Build Coastguard Worker         }
405*38e8c45fSAndroid Build Coastguard Worker 
406*38e8c45fSAndroid Build Coastguard Worker         testPrintI("==== Starting pass: %u", pass);
407*38e8c45fSAndroid Build Coastguard Worker 
408*38e8c45fSAndroid Build Coastguard Worker         // Cause deterministic sequence of prandom numbers to be
409*38e8c45fSAndroid Build Coastguard Worker         // generated for this pass.
410*38e8c45fSAndroid Build Coastguard Worker         srand48(pass);
411*38e8c45fSAndroid Build Coastguard Worker 
412*38e8c45fSAndroid Build Coastguard Worker         hwc_display_contents_1_t *list;
413*38e8c45fSAndroid Build Coastguard Worker         list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1);
414*38e8c45fSAndroid Build Coastguard Worker         if (list == NULL) {
415*38e8c45fSAndroid Build Coastguard Worker             testPrintE("hwcTestCreateLayerList failed");
416*38e8c45fSAndroid Build Coastguard Worker             exit(20);
417*38e8c45fSAndroid Build Coastguard Worker         }
418*38e8c45fSAndroid Build Coastguard Worker 
419*38e8c45fSAndroid Build Coastguard Worker         // Prandomly select a subset of frames to be used by this pass.
420*38e8c45fSAndroid Build Coastguard Worker         vector <vector <sp<GraphicBuffer> > > selectedFrames;
421*38e8c45fSAndroid Build Coastguard Worker         selectedFrames = vectorRandSelect(frames, list->numHwLayers);
422*38e8c45fSAndroid Build Coastguard Worker 
423*38e8c45fSAndroid Build Coastguard Worker         // Any transform tends to create a layer that the hardware
424*38e8c45fSAndroid Build Coastguard Worker         // composer is unable to support and thus has to leave for
425*38e8c45fSAndroid Build Coastguard Worker         // SurfaceFlinger.  Place heavy bias on specifying no transforms.
426*38e8c45fSAndroid Build Coastguard Worker         bool noTransform = testRandFract() > rareRatio;
427*38e8c45fSAndroid Build Coastguard Worker 
428*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
429*38e8c45fSAndroid Build Coastguard Worker             unsigned int idx = testRandMod(selectedFrames[n1].size());
430*38e8c45fSAndroid Build Coastguard Worker             sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
431*38e8c45fSAndroid Build Coastguard Worker             hwc_layer_1_t *layer = &list->hwLayers[n1];
432*38e8c45fSAndroid Build Coastguard Worker             layer->handle = gBuf->handle;
433*38e8c45fSAndroid Build Coastguard Worker 
434*38e8c45fSAndroid Build Coastguard Worker             layer->blending = blendingOps[testRandMod(NUMA(blendingOps))];
435*38e8c45fSAndroid Build Coastguard Worker             layer->flags = (testRandFract() > rareRatio) ? 0
436*38e8c45fSAndroid Build Coastguard Worker                 : vectorOr(vectorRandSelect(vecLayerFlags,
437*38e8c45fSAndroid Build Coastguard Worker                            testRandMod(vecLayerFlags.size() + 1)));
438*38e8c45fSAndroid Build Coastguard Worker             layer->transform = (noTransform || testRandFract() > rareRatio) ? 0
439*38e8c45fSAndroid Build Coastguard Worker                 : vectorOr(vectorRandSelect(vecTransformFlags,
440*38e8c45fSAndroid Build Coastguard Worker                            testRandMod(vecTransformFlags.size() + 1)));
441*38e8c45fSAndroid Build Coastguard Worker             layer->sourceCrop.left = testRandMod(gBuf->getWidth());
442*38e8c45fSAndroid Build Coastguard Worker             layer->sourceCrop.top = testRandMod(gBuf->getHeight());
443*38e8c45fSAndroid Build Coastguard Worker             layer->sourceCrop.right = layer->sourceCrop.left
444*38e8c45fSAndroid Build Coastguard Worker                 + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1;
445*38e8c45fSAndroid Build Coastguard Worker             layer->sourceCrop.bottom = layer->sourceCrop.top
446*38e8c45fSAndroid Build Coastguard Worker                 + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1;
447*38e8c45fSAndroid Build Coastguard Worker             layer->displayFrame.left = testRandMod(width);
448*38e8c45fSAndroid Build Coastguard Worker             layer->displayFrame.top = testRandMod(height);
449*38e8c45fSAndroid Build Coastguard Worker             layer->displayFrame.right = layer->displayFrame.left
450*38e8c45fSAndroid Build Coastguard Worker                 + testRandMod(width - layer->displayFrame.left) + 1;
451*38e8c45fSAndroid Build Coastguard Worker             layer->displayFrame.bottom = layer->displayFrame.top
452*38e8c45fSAndroid Build Coastguard Worker                 + testRandMod(height - layer->displayFrame.top) + 1;
453*38e8c45fSAndroid Build Coastguard Worker 
454*38e8c45fSAndroid Build Coastguard Worker             // Increase the frequency that a scale factor of 1.0 from
455*38e8c45fSAndroid Build Coastguard Worker             // the sourceCrop to displayFrame occurs.  This is the
456*38e8c45fSAndroid Build Coastguard Worker             // most common scale factor used by applications and would
457*38e8c45fSAndroid Build Coastguard Worker             // be rarely produced by this stress test without this
458*38e8c45fSAndroid Build Coastguard Worker             // logic.
459*38e8c45fSAndroid Build Coastguard Worker             if (testRandFract() <= freqRatio) {
460*38e8c45fSAndroid Build Coastguard Worker                 // Only change to scale factor to 1.0 if both the
461*38e8c45fSAndroid Build Coastguard Worker                 // width and height will fit.
462*38e8c45fSAndroid Build Coastguard Worker                 int sourceWidth = layer->sourceCrop.right
463*38e8c45fSAndroid Build Coastguard Worker                                   - layer->sourceCrop.left;
464*38e8c45fSAndroid Build Coastguard Worker                 int sourceHeight = layer->sourceCrop.bottom
465*38e8c45fSAndroid Build Coastguard Worker                                    - layer->sourceCrop.top;
466*38e8c45fSAndroid Build Coastguard Worker                 if (((layer->displayFrame.left + sourceWidth) <= width)
467*38e8c45fSAndroid Build Coastguard Worker                     && ((layer->displayFrame.top + sourceHeight) <= height)) {
468*38e8c45fSAndroid Build Coastguard Worker                     layer->displayFrame.right = layer->displayFrame.left
469*38e8c45fSAndroid Build Coastguard Worker                                                 + sourceWidth;
470*38e8c45fSAndroid Build Coastguard Worker                     layer->displayFrame.bottom = layer->displayFrame.top
471*38e8c45fSAndroid Build Coastguard Worker                                                  + sourceHeight;
472*38e8c45fSAndroid Build Coastguard Worker                 }
473*38e8c45fSAndroid Build Coastguard Worker             }
474*38e8c45fSAndroid Build Coastguard Worker 
475*38e8c45fSAndroid Build Coastguard Worker             layer->visibleRegionScreen.numRects = 1;
476*38e8c45fSAndroid Build Coastguard Worker             layer->visibleRegionScreen.rects = &layer->displayFrame;
477*38e8c45fSAndroid Build Coastguard Worker         }
478*38e8c45fSAndroid Build Coastguard Worker 
479*38e8c45fSAndroid Build Coastguard Worker         // Perform prepare operation
480*38e8c45fSAndroid Build Coastguard Worker         if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
481*38e8c45fSAndroid Build Coastguard Worker         hwcDevice->prepare(hwcDevice, 1, &list);
482*38e8c45fSAndroid Build Coastguard Worker         if (verbose) {
483*38e8c45fSAndroid Build Coastguard Worker             testPrintI("Post Prepare:");
484*38e8c45fSAndroid Build Coastguard Worker             hwcTestDisplayListPrepareModifiable(list);
485*38e8c45fSAndroid Build Coastguard Worker         }
486*38e8c45fSAndroid Build Coastguard Worker 
487*38e8c45fSAndroid Build Coastguard Worker         // Turn off the geometry changed flag
488*38e8c45fSAndroid Build Coastguard Worker         list->flags &= ~HWC_GEOMETRY_CHANGED;
489*38e8c45fSAndroid Build Coastguard Worker 
490*38e8c45fSAndroid Build Coastguard Worker         // Perform the set operation(s)
491*38e8c45fSAndroid Build Coastguard Worker         if (verbose) {testPrintI("Set:"); }
492*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int n1 = 0; n1 < numSet; n1++) {
493*38e8c45fSAndroid Build Coastguard Worker             if (verbose) { hwcTestDisplayListHandles(list); }
494*38e8c45fSAndroid Build Coastguard Worker             list->dpy = dpy;
495*38e8c45fSAndroid Build Coastguard Worker             list->sur = surface;
496*38e8c45fSAndroid Build Coastguard Worker             hwcDevice->set(hwcDevice, 1, &list);
497*38e8c45fSAndroid Build Coastguard Worker 
498*38e8c45fSAndroid Build Coastguard Worker             // Prandomly select a new set of handles
499*38e8c45fSAndroid Build Coastguard Worker             for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
500*38e8c45fSAndroid Build Coastguard Worker                 unsigned int idx = testRandMod(selectedFrames[n1].size());
501*38e8c45fSAndroid Build Coastguard Worker                 sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
502*38e8c45fSAndroid Build Coastguard Worker                 hwc_layer_1_t *layer = &list->hwLayers[n1];
503*38e8c45fSAndroid Build Coastguard Worker                 layer->handle = (native_handle_t *) gBuf->handle;
504*38e8c45fSAndroid Build Coastguard Worker             }
505*38e8c45fSAndroid Build Coastguard Worker 
506*38e8c45fSAndroid Build Coastguard Worker             testDelay(perSetDelay);
507*38e8c45fSAndroid Build Coastguard Worker         }
508*38e8c45fSAndroid Build Coastguard Worker 
509*38e8c45fSAndroid Build Coastguard Worker         hwcTestFreeLayerList(list);
510*38e8c45fSAndroid Build Coastguard Worker         testPrintI("==== Completed pass: %u", pass);
511*38e8c45fSAndroid Build Coastguard Worker     }
512*38e8c45fSAndroid Build Coastguard Worker 
513*38e8c45fSAndroid Build Coastguard Worker     testDelay(endDelay);
514*38e8c45fSAndroid Build Coastguard Worker 
515*38e8c45fSAndroid Build Coastguard Worker     // Start framework
516*38e8c45fSAndroid Build Coastguard Worker     rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
517*38e8c45fSAndroid Build Coastguard Worker     if (rv >= (signed) sizeof(cmd) - 1) {
518*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
519*38e8c45fSAndroid Build Coastguard Worker         exit(21);
520*38e8c45fSAndroid Build Coastguard Worker     }
521*38e8c45fSAndroid Build Coastguard Worker     testExecCmd(cmd);
522*38e8c45fSAndroid Build Coastguard Worker 
523*38e8c45fSAndroid Build Coastguard Worker     testPrintI("Successfully completed %u passes", pass - startPass);
524*38e8c45fSAndroid Build Coastguard Worker 
525*38e8c45fSAndroid Build Coastguard Worker     return 0;
526*38e8c45fSAndroid Build Coastguard Worker }
527*38e8c45fSAndroid Build Coastguard Worker 
init(void)528*38e8c45fSAndroid Build Coastguard Worker void init(void)
529*38e8c45fSAndroid Build Coastguard Worker {
530*38e8c45fSAndroid Build Coastguard Worker     srand48(0); // Defensively set pseudo random number generator.
531*38e8c45fSAndroid Build Coastguard Worker                 // Should not need to set this, because a stress test
532*38e8c45fSAndroid Build Coastguard Worker                 // sets the seed on each pass.  Defensively set it here
533*38e8c45fSAndroid Build Coastguard Worker                 // so that future code that uses pseudo random numbers
534*38e8c45fSAndroid Build Coastguard Worker                 // before the first pass will be deterministic.
535*38e8c45fSAndroid Build Coastguard Worker 
536*38e8c45fSAndroid Build Coastguard Worker     hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
537*38e8c45fSAndroid Build Coastguard Worker 
538*38e8c45fSAndroid Build Coastguard Worker     hwcTestOpenHwc(&hwcDevice);
539*38e8c45fSAndroid Build Coastguard Worker }
540*38e8c45fSAndroid Build Coastguard Worker 
541*38e8c45fSAndroid Build Coastguard Worker /*
542*38e8c45fSAndroid Build Coastguard Worker  * Initialize Frames
543*38e8c45fSAndroid Build Coastguard Worker  *
544*38e8c45fSAndroid Build Coastguard Worker  * Creates an array of graphic buffers, within the global variable
545*38e8c45fSAndroid Build Coastguard Worker  * named frames.  The graphic buffers are contained within a vector of
546*38e8c45fSAndroid Build Coastguard Worker  * vectors.  All the graphic buffers in a particular row are of the same
547*38e8c45fSAndroid Build Coastguard Worker  * format and dimension.  Each graphic buffer is uniformly filled with a
548*38e8c45fSAndroid Build Coastguard Worker  * prandomly selected color.  It is likely that each buffer, even
549*38e8c45fSAndroid Build Coastguard Worker  * in the same row, will be filled with a unique color.
550*38e8c45fSAndroid Build Coastguard Worker  */
initFrames(unsigned int seed)551*38e8c45fSAndroid Build Coastguard Worker void initFrames(unsigned int seed)
552*38e8c45fSAndroid Build Coastguard Worker {
553*38e8c45fSAndroid Build Coastguard Worker     int rv;
554*38e8c45fSAndroid Build Coastguard Worker     const size_t maxRows = 5;
555*38e8c45fSAndroid Build Coastguard Worker     const size_t minCols = 2;  // Need at least double buffering
556*38e8c45fSAndroid Build Coastguard Worker     const size_t maxCols = 4;  // One more than triple buffering
557*38e8c45fSAndroid Build Coastguard Worker 
558*38e8c45fSAndroid Build Coastguard Worker     if (verbose) { testPrintI("initFrames seed: %u", seed); }
559*38e8c45fSAndroid Build Coastguard Worker     srand48(seed);
560*38e8c45fSAndroid Build Coastguard Worker     size_t rows = testRandMod(maxRows) + 1;
561*38e8c45fSAndroid Build Coastguard Worker 
562*38e8c45fSAndroid Build Coastguard Worker     frames.clear();
563*38e8c45fSAndroid Build Coastguard Worker     frames.resize(rows);
564*38e8c45fSAndroid Build Coastguard Worker 
565*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int row = 0; row < rows; row++) {
566*38e8c45fSAndroid Build Coastguard Worker         // All frames within a row have to have the same format and
567*38e8c45fSAndroid Build Coastguard Worker         // dimensions.  Width and height need to be >= 1.
568*38e8c45fSAndroid Build Coastguard Worker         unsigned int formatIdx = testRandMod(NUMA(hwcTestGraphicFormat));
569*38e8c45fSAndroid Build Coastguard Worker         const struct hwcTestGraphicFormat *formatPtr
570*38e8c45fSAndroid Build Coastguard Worker             = &hwcTestGraphicFormat[formatIdx];
571*38e8c45fSAndroid Build Coastguard Worker         int format = formatPtr->format;
572*38e8c45fSAndroid Build Coastguard Worker 
573*38e8c45fSAndroid Build Coastguard Worker         // Pick width and height, which must be >= 1 and the size
574*38e8c45fSAndroid Build Coastguard Worker         // mod the wMod/hMod value must be equal to 0.
575*38e8c45fSAndroid Build Coastguard Worker         size_t w = (width * maxSizeRatio) * testRandFract();
576*38e8c45fSAndroid Build Coastguard Worker         size_t h = (height * maxSizeRatio) * testRandFract();
577*38e8c45fSAndroid Build Coastguard Worker         w = max(size_t(1u), w);
578*38e8c45fSAndroid Build Coastguard Worker         h = max(size_t(1u), h);
579*38e8c45fSAndroid Build Coastguard Worker         if ((w % formatPtr->wMod) != 0) {
580*38e8c45fSAndroid Build Coastguard Worker             w += formatPtr->wMod - (w % formatPtr->wMod);
581*38e8c45fSAndroid Build Coastguard Worker         }
582*38e8c45fSAndroid Build Coastguard Worker         if ((h % formatPtr->hMod) != 0) {
583*38e8c45fSAndroid Build Coastguard Worker             h += formatPtr->hMod - (h % formatPtr->hMod);
584*38e8c45fSAndroid Build Coastguard Worker         }
585*38e8c45fSAndroid Build Coastguard Worker         if (verbose) {
586*38e8c45fSAndroid Build Coastguard Worker             testPrintI("  frame %u width: %u height: %u format: %u %s",
587*38e8c45fSAndroid Build Coastguard Worker                        row, w, h, format, hwcTestGraphicFormat2str(format));
588*38e8c45fSAndroid Build Coastguard Worker         }
589*38e8c45fSAndroid Build Coastguard Worker 
590*38e8c45fSAndroid Build Coastguard Worker         size_t cols = testRandMod((maxCols + 1) - minCols) + minCols;
591*38e8c45fSAndroid Build Coastguard Worker         frames[row].resize(cols);
592*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int col = 0; col < cols; col++) {
593*38e8c45fSAndroid Build Coastguard Worker             ColorFract color(testRandFract(), testRandFract(), testRandFract());
594*38e8c45fSAndroid Build Coastguard Worker             float alpha = testRandFract();
595*38e8c45fSAndroid Build Coastguard Worker 
596*38e8c45fSAndroid Build Coastguard Worker             frames[row][col] = new GraphicBuffer(w, h, format, texUsage);
597*38e8c45fSAndroid Build Coastguard Worker             if ((rv = frames[row][col]->initCheck()) != NO_ERROR) {
598*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("GraphicBuffer initCheck failed, rv: %i", rv);
599*38e8c45fSAndroid Build Coastguard Worker                 testPrintE("  frame %u width: %u height: %u format: %u %s",
600*38e8c45fSAndroid Build Coastguard Worker                            row, w, h, format, hwcTestGraphicFormat2str(format));
601*38e8c45fSAndroid Build Coastguard Worker                 exit(80);
602*38e8c45fSAndroid Build Coastguard Worker             }
603*38e8c45fSAndroid Build Coastguard Worker 
604*38e8c45fSAndroid Build Coastguard Worker             hwcTestFillColor(frames[row][col].get(), color, alpha);
605*38e8c45fSAndroid Build Coastguard Worker             if (verbose) {
606*38e8c45fSAndroid Build Coastguard Worker                 testPrintI("    buf: %p handle: %p color: %s alpha: %f",
607*38e8c45fSAndroid Build Coastguard Worker                            frames[row][col].get(), frames[row][col]->handle,
608*38e8c45fSAndroid Build Coastguard Worker                            string(color).c_str(), alpha);
609*38e8c45fSAndroid Build Coastguard Worker             }
610*38e8c45fSAndroid Build Coastguard Worker         }
611*38e8c45fSAndroid Build Coastguard Worker     }
612*38e8c45fSAndroid Build Coastguard Worker }
613*38e8c45fSAndroid Build Coastguard Worker 
614*38e8c45fSAndroid Build Coastguard Worker /*
615*38e8c45fSAndroid Build Coastguard Worker  * Vector Random Select
616*38e8c45fSAndroid Build Coastguard Worker  *
617*38e8c45fSAndroid Build Coastguard Worker  * Prandomly selects and returns num elements from vec.
618*38e8c45fSAndroid Build Coastguard Worker  */
619*38e8c45fSAndroid Build Coastguard Worker template <class T>
vectorRandSelect(const vector<T> & vec,size_t num)620*38e8c45fSAndroid Build Coastguard Worker vector<T> vectorRandSelect(const vector<T>& vec, size_t num)
621*38e8c45fSAndroid Build Coastguard Worker {
622*38e8c45fSAndroid Build Coastguard Worker     vector<T> rv = vec;
623*38e8c45fSAndroid Build Coastguard Worker 
624*38e8c45fSAndroid Build Coastguard Worker     while (rv.size() > num) {
625*38e8c45fSAndroid Build Coastguard Worker         rv.erase(rv.begin() + testRandMod(rv.size()));
626*38e8c45fSAndroid Build Coastguard Worker     }
627*38e8c45fSAndroid Build Coastguard Worker 
628*38e8c45fSAndroid Build Coastguard Worker     return rv;
629*38e8c45fSAndroid Build Coastguard Worker }
630*38e8c45fSAndroid Build Coastguard Worker 
631*38e8c45fSAndroid Build Coastguard Worker /*
632*38e8c45fSAndroid Build Coastguard Worker  * Vector Or
633*38e8c45fSAndroid Build Coastguard Worker  *
634*38e8c45fSAndroid Build Coastguard Worker  * Or's togethen the values of each element of vec and returns the result.
635*38e8c45fSAndroid Build Coastguard Worker  */
636*38e8c45fSAndroid Build Coastguard Worker template <class T>
vectorOr(const vector<T> & vec)637*38e8c45fSAndroid Build Coastguard Worker T vectorOr(const vector<T>& vec)
638*38e8c45fSAndroid Build Coastguard Worker {
639*38e8c45fSAndroid Build Coastguard Worker     T rv = 0;
640*38e8c45fSAndroid Build Coastguard Worker 
641*38e8c45fSAndroid Build Coastguard Worker     for (size_t n1 = 0; n1 < vec.size(); n1++) {
642*38e8c45fSAndroid Build Coastguard Worker         rv |= vec[n1];
643*38e8c45fSAndroid Build Coastguard Worker     }
644*38e8c45fSAndroid Build Coastguard Worker 
645*38e8c45fSAndroid Build Coastguard Worker     return rv;
646*38e8c45fSAndroid Build Coastguard Worker }
647