xref: /aosp_15_r20/frameworks/native/opengl/tests/hwc/hwcCommit.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2011 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 Commit Points
20*38e8c45fSAndroid Build Coastguard Worker  *
21*38e8c45fSAndroid Build Coastguard Worker  * Synopsis
22*38e8c45fSAndroid Build Coastguard Worker  *   hwcCommit [options] graphicFormat ...
23*38e8c45fSAndroid Build Coastguard Worker  *     options:
24*38e8c45fSAndroid Build Coastguard Worker  *       -s [width, height] - Starting dimension
25*38e8c45fSAndroid Build Coastguard Worker  *       -v - Verbose
26*38e8c45fSAndroid Build Coastguard Worker  *
27*38e8c45fSAndroid Build Coastguard Worker  *      graphic formats:
28*38e8c45fSAndroid Build Coastguard Worker  *        RGBA8888 (reference frame default)
29*38e8c45fSAndroid Build Coastguard Worker  *        RGBX8888
30*38e8c45fSAndroid Build Coastguard Worker  *        RGB888
31*38e8c45fSAndroid Build Coastguard Worker  *        RGB565
32*38e8c45fSAndroid Build Coastguard Worker  *        BGRA8888
33*38e8c45fSAndroid Build Coastguard Worker  *        RGBA5551
34*38e8c45fSAndroid Build Coastguard Worker  *        RGBA4444
35*38e8c45fSAndroid Build Coastguard Worker  *        YV12
36*38e8c45fSAndroid Build Coastguard Worker  *
37*38e8c45fSAndroid Build Coastguard Worker  * Description
38*38e8c45fSAndroid Build Coastguard Worker  *   The Hardware Composer (HWC) Commit test is a benchmark that
39*38e8c45fSAndroid Build Coastguard Worker  *   discovers the points at which the HWC will commit to rendering an
40*38e8c45fSAndroid Build Coastguard Worker  *   overlay(s).  Before rendering a set of overlays, the HWC is shown
41*38e8c45fSAndroid Build Coastguard Worker  *   the list through a prepare call.  During the prepare call the HWC
42*38e8c45fSAndroid Build Coastguard Worker  *   is able to examine the list and specify which overlays it is able
43*38e8c45fSAndroid Build Coastguard Worker  *   to handle.  The overlays that it can't handle are typically composited
44*38e8c45fSAndroid Build Coastguard Worker  *   by a higher level (e.g. Surface Flinger) and then the original list
45*38e8c45fSAndroid Build Coastguard Worker  *   plus a composit of what HWC passed on are provided back to the HWC
46*38e8c45fSAndroid Build Coastguard Worker  *   for rendering.
47*38e8c45fSAndroid Build Coastguard Worker  *
48*38e8c45fSAndroid Build Coastguard Worker  *   Once an implementation of the HWC has been shipped, a regression would
49*38e8c45fSAndroid Build Coastguard Worker  *   likely occur if a latter implementation started passing on conditions
50*38e8c45fSAndroid Build Coastguard Worker  *   that it used to commit to.  The primary purpose of this benchmark
51*38e8c45fSAndroid Build Coastguard Worker  *   is the automated discovery of the commit points, where an implementation
52*38e8c45fSAndroid Build Coastguard Worker  *   is on the edge between committing and not committing.  These are commonly
53*38e8c45fSAndroid Build Coastguard Worker  *   referred to as commit points.  Between implementations changes to the
54*38e8c45fSAndroid Build Coastguard Worker  *   commit points are allowed, as long as they improve what the HWC commits
55*38e8c45fSAndroid Build Coastguard Worker  *   to.  Once an implementation of the HWC is shipped, the commit points are
56*38e8c45fSAndroid Build Coastguard Worker  *   not allowed to regress in future implementations.
57*38e8c45fSAndroid Build Coastguard Worker  *
58*38e8c45fSAndroid Build Coastguard Worker  *   This benchmark takes a sampling and then adjusts until it finds a
59*38e8c45fSAndroid Build Coastguard Worker  *   commit point.  It doesn't exhaustively check all possible conditions,
60*38e8c45fSAndroid Build Coastguard Worker  *   which do to the number of combinations would be impossible.  Instead
61*38e8c45fSAndroid Build Coastguard Worker  *   it starts its search from a starting dimension, that can be changed
62*38e8c45fSAndroid Build Coastguard Worker  *   via the -s option.  The search is also bounded by a set of search
63*38e8c45fSAndroid Build Coastguard Worker  *   limits, that are hard-coded into a structure of constants named
64*38e8c45fSAndroid Build Coastguard Worker  *   searchLimits.  Results that happen to reach a searchLimit are prefixed
65*38e8c45fSAndroid Build Coastguard Worker  *   with >=, so that it is known that the value could possibly be larger.
66*38e8c45fSAndroid Build Coastguard Worker  *
67*38e8c45fSAndroid Build Coastguard Worker  *   Measurements are made for each of the graphic formats specified as
68*38e8c45fSAndroid Build Coastguard Worker  *   positional parameters on the command-line.  If no graphic formats
69*38e8c45fSAndroid Build Coastguard Worker  *   are specified on the command line, then by default measurements are
70*38e8c45fSAndroid Build Coastguard Worker  *   made and reported for each of the known graphic format.
71*38e8c45fSAndroid Build Coastguard Worker  */
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "hwcCommitTest"
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
76*38e8c45fSAndroid Build Coastguard Worker #include <assert.h>
77*38e8c45fSAndroid Build Coastguard Worker #include <cerrno>
78*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
79*38e8c45fSAndroid Build Coastguard Worker #include <cstdlib>
80*38e8c45fSAndroid Build Coastguard Worker #include <ctime>
81*38e8c45fSAndroid Build Coastguard Worker #include <iomanip>
82*38e8c45fSAndroid Build Coastguard Worker #include <istream>
83*38e8c45fSAndroid Build Coastguard Worker #include <libgen.h>
84*38e8c45fSAndroid Build Coastguard Worker #include <list>
85*38e8c45fSAndroid Build Coastguard Worker #include <sched.h>
86*38e8c45fSAndroid Build Coastguard Worker #include <sstream>
87*38e8c45fSAndroid Build Coastguard Worker #include <stdint.h>
88*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
89*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
90*38e8c45fSAndroid Build Coastguard Worker #include <vector>
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker #include <sys/syscall.h>
93*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
94*38e8c45fSAndroid Build Coastguard Worker #include <sys/wait.h>
95*38e8c45fSAndroid Build Coastguard Worker 
96*38e8c45fSAndroid Build Coastguard Worker #include <EGL/egl.h>
97*38e8c45fSAndroid Build Coastguard Worker #include <EGL/eglext.h>
98*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
99*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2ext.h>
100*38e8c45fSAndroid Build Coastguard Worker 
101*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
104*38e8c45fSAndroid Build Coastguard Worker #include <testUtil.h>
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker #include <hardware/hwcomposer.h>
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker #include <glTestLib.h>
109*38e8c45fSAndroid Build Coastguard Worker #include "hwcTestLib.h"
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker using namespace std;
112*38e8c45fSAndroid Build Coastguard Worker using namespace android;
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker // Defaults
115*38e8c45fSAndroid Build Coastguard Worker const HwcTestDim defaultStartDim = HwcTestDim(100, 100);
116*38e8c45fSAndroid Build Coastguard Worker const bool defaultVerbose = false;
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker const uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
119*38e8c45fSAndroid Build Coastguard Worker const int32_t    defaultTransform = 0;
120*38e8c45fSAndroid Build Coastguard Worker const uint32_t   defaultBlend = HWC_BLENDING_NONE;
121*38e8c45fSAndroid Build Coastguard Worker const ColorFract defaultColor(0.5, 0.5, 0.5);
122*38e8c45fSAndroid Build Coastguard Worker const float      defaultAlpha = 1.0; // Opaque
123*38e8c45fSAndroid Build Coastguard Worker const HwcTestDim defaultSourceDim(1, 1);
124*38e8c45fSAndroid Build Coastguard Worker 
125*38e8c45fSAndroid Build Coastguard Worker // Global Constants
126*38e8c45fSAndroid Build Coastguard Worker const uint32_t printFieldWidth = 2;
127*38e8c45fSAndroid Build Coastguard Worker const struct searchLimits {
128*38e8c45fSAndroid Build Coastguard Worker     uint32_t   numOverlays;
129*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim sourceCrop;
130*38e8c45fSAndroid Build Coastguard Worker } searchLimits = {
131*38e8c45fSAndroid Build Coastguard Worker     10,
132*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim(3000, 2000),
133*38e8c45fSAndroid Build Coastguard Worker };
134*38e8c45fSAndroid Build Coastguard Worker const struct transformType {
135*38e8c45fSAndroid Build Coastguard Worker     const char *desc;
136*38e8c45fSAndroid Build Coastguard Worker     uint32_t id;
137*38e8c45fSAndroid Build Coastguard Worker } transformType[] = {
138*38e8c45fSAndroid Build Coastguard Worker     {"fliph",  HWC_TRANSFORM_FLIP_H},
139*38e8c45fSAndroid Build Coastguard Worker     {"flipv",  HWC_TRANSFORM_FLIP_V},
140*38e8c45fSAndroid Build Coastguard Worker     {"rot90",  HWC_TRANSFORM_ROT_90},
141*38e8c45fSAndroid Build Coastguard Worker     {"rot180", HWC_TRANSFORM_ROT_180},
142*38e8c45fSAndroid Build Coastguard Worker     {"rot270", HWC_TRANSFORM_ROT_270},
143*38e8c45fSAndroid Build Coastguard Worker };
144*38e8c45fSAndroid Build Coastguard Worker const struct blendType {
145*38e8c45fSAndroid Build Coastguard Worker     const char *desc;
146*38e8c45fSAndroid Build Coastguard Worker     uint32_t id;
147*38e8c45fSAndroid Build Coastguard Worker } blendType[] = {
148*38e8c45fSAndroid Build Coastguard Worker     {"none", HWC_BLENDING_NONE},
149*38e8c45fSAndroid Build Coastguard Worker     {"premult", HWC_BLENDING_PREMULT},
150*38e8c45fSAndroid Build Coastguard Worker     {"coverage", HWC_BLENDING_COVERAGE},
151*38e8c45fSAndroid Build Coastguard Worker };
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker // Defines
154*38e8c45fSAndroid Build Coastguard Worker #define MAXCMD               200
155*38e8c45fSAndroid Build Coastguard Worker #define CMD_STOP_FRAMEWORK   "stop 2>&1"
156*38e8c45fSAndroid Build Coastguard Worker #define CMD_START_FRAMEWORK  "start 2>&1"
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker // Macros
159*38e8c45fSAndroid Build Coastguard Worker #define NUMA(a) (sizeof(a) / sizeof((a)[0])) // Num elements in an array
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker // Local types
162*38e8c45fSAndroid Build Coastguard Worker class Rectangle {
163*38e8c45fSAndroid Build Coastguard Worker public:
164*38e8c45fSAndroid Build Coastguard Worker     explicit Rectangle(uint32_t graphicFormat = defaultFormat,
165*38e8c45fSAndroid Build Coastguard Worker               HwcTestDim dfDim = HwcTestDim(1, 1),
166*38e8c45fSAndroid Build Coastguard Worker               HwcTestDim sDim = HwcTestDim(1, 1));
167*38e8c45fSAndroid Build Coastguard Worker     void setSourceDim(HwcTestDim dim);
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker     uint32_t     format;
170*38e8c45fSAndroid Build Coastguard Worker     uint32_t     transform;
171*38e8c45fSAndroid Build Coastguard Worker     int32_t      blend;
172*38e8c45fSAndroid Build Coastguard Worker     ColorFract   color;
173*38e8c45fSAndroid Build Coastguard Worker     float        alpha;
174*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim   sourceDim;
175*38e8c45fSAndroid Build Coastguard Worker     struct hwc_rect   sourceCrop;
176*38e8c45fSAndroid Build Coastguard Worker     struct hwc_rect   displayFrame;
177*38e8c45fSAndroid Build Coastguard Worker };
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker class Range {
180*38e8c45fSAndroid Build Coastguard Worker public:
Range(void)181*38e8c45fSAndroid Build Coastguard Worker     Range(void) : _l(0), _u(0) {}
Range(uint32_t lower,uint32_t upper)182*38e8c45fSAndroid Build Coastguard Worker     Range(uint32_t lower, uint32_t upper) : _l(lower), _u(upper) {}
lower(void)183*38e8c45fSAndroid Build Coastguard Worker     uint32_t lower(void) { return _l; }
upper(void)184*38e8c45fSAndroid Build Coastguard Worker     uint32_t upper(void) { return _u; }
185*38e8c45fSAndroid Build Coastguard Worker 
186*38e8c45fSAndroid Build Coastguard Worker     operator string(); // NOLINT(google-explicit-constructor)
187*38e8c45fSAndroid Build Coastguard Worker 
188*38e8c45fSAndroid Build Coastguard Worker private:
189*38e8c45fSAndroid Build Coastguard Worker     uint32_t _l; // lower
190*38e8c45fSAndroid Build Coastguard Worker     uint32_t _u; // upper
191*38e8c45fSAndroid Build Coastguard Worker };
192*38e8c45fSAndroid Build Coastguard Worker 
operator string()193*38e8c45fSAndroid Build Coastguard Worker Range::operator string()
194*38e8c45fSAndroid Build Coastguard Worker {
195*38e8c45fSAndroid Build Coastguard Worker     ostringstream out;
196*38e8c45fSAndroid Build Coastguard Worker 
197*38e8c45fSAndroid Build Coastguard Worker     out << '[' << _l << ", " << _u << ']';
198*38e8c45fSAndroid Build Coastguard Worker 
199*38e8c45fSAndroid Build Coastguard Worker     return out.str();
200*38e8c45fSAndroid Build Coastguard Worker }
201*38e8c45fSAndroid Build Coastguard Worker 
202*38e8c45fSAndroid Build Coastguard Worker class Rational {
203*38e8c45fSAndroid Build Coastguard Worker public:
Rational(void)204*38e8c45fSAndroid Build Coastguard Worker     Rational(void) : _n(0), _d(1) {}
Rational(uint32_t n,uint32_t d)205*38e8c45fSAndroid Build Coastguard Worker     Rational(uint32_t n, uint32_t d) : _n(n), _d(d) {}
numerator(void)206*38e8c45fSAndroid Build Coastguard Worker     uint32_t numerator(void) { return _n; }
denominator(void)207*38e8c45fSAndroid Build Coastguard Worker     uint32_t denominator(void) { return _d; }
setNumerator(uint32_t numerator)208*38e8c45fSAndroid Build Coastguard Worker     void setNumerator(uint32_t numerator) { _n = numerator; }
209*38e8c45fSAndroid Build Coastguard Worker 
210*38e8c45fSAndroid Build Coastguard Worker     bool operator==(const Rational& other) const;
operator !=(const Rational & other) const211*38e8c45fSAndroid Build Coastguard Worker     bool operator!=(const Rational& other) const { return !(*this == other); }
212*38e8c45fSAndroid Build Coastguard Worker     bool operator<(const Rational& other) const;
operator >(const Rational & other) const213*38e8c45fSAndroid Build Coastguard Worker     bool operator>(const Rational& other) const {
214*38e8c45fSAndroid Build Coastguard Worker         return (!(*this == other) && !(*this < other));
215*38e8c45fSAndroid Build Coastguard Worker     }
216*38e8c45fSAndroid Build Coastguard Worker     static void double2Rational(double f, Range nRange, Range dRange,
217*38e8c45fSAndroid Build Coastguard Worker                                Rational& lower, Rational& upper);
218*38e8c45fSAndroid Build Coastguard Worker 
219*38e8c45fSAndroid Build Coastguard Worker     // NOLINTNEXTLINE(google-explicit-constructor)
220*38e8c45fSAndroid Build Coastguard Worker     operator string() const;
221*38e8c45fSAndroid Build Coastguard Worker     // NOLINTNEXTLINE(google-explicit-constructor)
operator double() const222*38e8c45fSAndroid Build Coastguard Worker     operator double() const { return (double) _n / (double) _d; }
223*38e8c45fSAndroid Build Coastguard Worker 
224*38e8c45fSAndroid Build Coastguard Worker 
225*38e8c45fSAndroid Build Coastguard Worker private:
226*38e8c45fSAndroid Build Coastguard Worker     uint32_t _n;
227*38e8c45fSAndroid Build Coastguard Worker     uint32_t _d;
228*38e8c45fSAndroid Build Coastguard Worker };
229*38e8c45fSAndroid Build Coastguard Worker 
230*38e8c45fSAndroid Build Coastguard Worker // Globals
231*38e8c45fSAndroid Build Coastguard Worker static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
232*38e8c45fSAndroid Build Coastguard Worker         GraphicBuffer::USAGE_SW_WRITE_RARELY;
233*38e8c45fSAndroid Build Coastguard Worker static hwc_composer_device_1_t *hwcDevice;
234*38e8c45fSAndroid Build Coastguard Worker static EGLDisplay dpy;
235*38e8c45fSAndroid Build Coastguard Worker static EGLSurface surface;
236*38e8c45fSAndroid Build Coastguard Worker static EGLint width, height;
237*38e8c45fSAndroid Build Coastguard Worker static size_t maxHeadingLen;
238*38e8c45fSAndroid Build Coastguard Worker static vector<string> formats;
239*38e8c45fSAndroid Build Coastguard Worker 
240*38e8c45fSAndroid Build Coastguard Worker // Measurements
241*38e8c45fSAndroid Build Coastguard Worker struct meas {
242*38e8c45fSAndroid Build Coastguard Worker     uint32_t format;
243*38e8c45fSAndroid Build Coastguard Worker     uint32_t startDimOverlays;
244*38e8c45fSAndroid Build Coastguard Worker     uint32_t maxNonOverlapping;
245*38e8c45fSAndroid Build Coastguard Worker     uint32_t maxOverlapping;
246*38e8c45fSAndroid Build Coastguard Worker     list<uint32_t> transforms;
247*38e8c45fSAndroid Build Coastguard Worker     list<uint32_t> blends;
248*38e8c45fSAndroid Build Coastguard Worker     struct displayFrame {
249*38e8c45fSAndroid Build Coastguard Worker         uint32_t minWidth;
250*38e8c45fSAndroid Build Coastguard Worker         uint32_t minHeight;
251*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim minDim;
252*38e8c45fSAndroid Build Coastguard Worker         uint32_t maxWidth;
253*38e8c45fSAndroid Build Coastguard Worker         uint32_t maxHeight;
254*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim maxDim;
255*38e8c45fSAndroid Build Coastguard Worker     } df;
256*38e8c45fSAndroid Build Coastguard Worker     struct sourceCrop {
257*38e8c45fSAndroid Build Coastguard Worker         uint32_t minWidth;
258*38e8c45fSAndroid Build Coastguard Worker         uint32_t minHeight;
259*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim minDim;
260*38e8c45fSAndroid Build Coastguard Worker         uint32_t maxWidth;
261*38e8c45fSAndroid Build Coastguard Worker         uint32_t maxHeight;
262*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim maxDim;
263*38e8c45fSAndroid Build Coastguard Worker         Rational hScale;
264*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim hScaleBestDf;
265*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim hScaleBestSc;
266*38e8c45fSAndroid Build Coastguard Worker         Rational vScale;
267*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim vScaleBestDf;
268*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim vScaleBestSc;
269*38e8c45fSAndroid Build Coastguard Worker     } sc;
270*38e8c45fSAndroid Build Coastguard Worker     vector<uint32_t> overlapBlendNone;
271*38e8c45fSAndroid Build Coastguard Worker     vector<uint32_t> overlapBlendPremult;
272*38e8c45fSAndroid Build Coastguard Worker     vector<uint32_t> overlapBlendCoverage;
273*38e8c45fSAndroid Build Coastguard Worker };
274*38e8c45fSAndroid Build Coastguard Worker vector<meas> measurements;
275*38e8c45fSAndroid Build Coastguard Worker 
276*38e8c45fSAndroid Build Coastguard Worker // Function prototypes
277*38e8c45fSAndroid Build Coastguard Worker uint32_t numOverlays(list<Rectangle>& rectList);
278*38e8c45fSAndroid Build Coastguard Worker uint32_t maxOverlays(uint32_t format, bool allowOverlap);
279*38e8c45fSAndroid Build Coastguard Worker list<uint32_t> supportedTransforms(uint32_t format);
280*38e8c45fSAndroid Build Coastguard Worker list<uint32_t> supportedBlends(uint32_t format);
281*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMinWidth(uint32_t format);
282*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMinHeight(uint32_t format);
283*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMaxWidth(uint32_t format);
284*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMaxHeight(uint32_t format);
285*38e8c45fSAndroid Build Coastguard Worker HwcTestDim dfMinDim(uint32_t format);
286*38e8c45fSAndroid Build Coastguard Worker HwcTestDim dfMaxDim(uint32_t format);
287*38e8c45fSAndroid Build Coastguard Worker uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim);
288*38e8c45fSAndroid Build Coastguard Worker uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim);
289*38e8c45fSAndroid Build Coastguard Worker uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim);
290*38e8c45fSAndroid Build Coastguard Worker uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim);
291*38e8c45fSAndroid Build Coastguard Worker HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim);
292*38e8c45fSAndroid Build Coastguard Worker HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim);
293*38e8c45fSAndroid Build Coastguard Worker Rational scHScale(uint32_t format,
294*38e8c45fSAndroid Build Coastguard Worker                   const HwcTestDim& dfMin, const HwcTestDim& dfMax,
295*38e8c45fSAndroid Build Coastguard Worker                   const HwcTestDim& scMin, const HwcTestDim& scMax,
296*38e8c45fSAndroid Build Coastguard Worker                   HwcTestDim& outBestDf, HwcTestDim& outBestSc);
297*38e8c45fSAndroid Build Coastguard Worker Rational scVScale(uint32_t format,
298*38e8c45fSAndroid Build Coastguard Worker                   const HwcTestDim& dfMin, const HwcTestDim& dfMax,
299*38e8c45fSAndroid Build Coastguard Worker                   const HwcTestDim& scMin, const HwcTestDim& scMax,
300*38e8c45fSAndroid Build Coastguard Worker                   HwcTestDim& outBestDf, HwcTestDim& outBestSc);
301*38e8c45fSAndroid Build Coastguard Worker uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
302*38e8c45fSAndroid Build Coastguard Worker                         uint32_t backgroundBlend, uint32_t foregroundBlend);
303*38e8c45fSAndroid Build Coastguard Worker string transformList2str(const list<uint32_t>& transformList);
304*38e8c45fSAndroid Build Coastguard Worker string blendList2str(const list<uint32_t>& blendList);
305*38e8c45fSAndroid Build Coastguard Worker void init(void);
306*38e8c45fSAndroid Build Coastguard Worker void printFormatHeadings(size_t indent);
307*38e8c45fSAndroid Build Coastguard Worker void printOverlapLine(size_t indent, const string formatStr,
308*38e8c45fSAndroid Build Coastguard Worker                       const vector<uint32_t>& results);
309*38e8c45fSAndroid Build Coastguard Worker void printSyntax(const char *cmd);
310*38e8c45fSAndroid Build Coastguard Worker 
311*38e8c45fSAndroid Build Coastguard Worker // Command-line option settings
312*38e8c45fSAndroid Build Coastguard Worker static bool verbose = defaultVerbose;
313*38e8c45fSAndroid Build Coastguard Worker static HwcTestDim startDim = defaultStartDim;
314*38e8c45fSAndroid Build Coastguard Worker 
315*38e8c45fSAndroid Build Coastguard Worker /*
316*38e8c45fSAndroid Build Coastguard Worker  * Main
317*38e8c45fSAndroid Build Coastguard Worker  *
318*38e8c45fSAndroid Build Coastguard Worker  * Performs the following high-level sequence of operations:
319*38e8c45fSAndroid Build Coastguard Worker  *
320*38e8c45fSAndroid Build Coastguard Worker  *   1. Command-line parsing
321*38e8c45fSAndroid Build Coastguard Worker  *
322*38e8c45fSAndroid Build Coastguard Worker  *   2. Form a list of command-line specified graphic formats.  If
323*38e8c45fSAndroid Build Coastguard Worker  *      no formats are specified, then form a list of all known formats.
324*38e8c45fSAndroid Build Coastguard Worker  *
325*38e8c45fSAndroid Build Coastguard Worker  *   3. Stop framework
326*38e8c45fSAndroid Build Coastguard Worker  *      Only one user at a time is allowed to use the HWC.  Surface
327*38e8c45fSAndroid Build Coastguard Worker  *      Flinger uses the HWC and is part of the framework.  Need to
328*38e8c45fSAndroid Build Coastguard Worker  *      stop the framework so that Surface Flinger will stop using
329*38e8c45fSAndroid Build Coastguard Worker  *      the HWC.
330*38e8c45fSAndroid Build Coastguard Worker  *
331*38e8c45fSAndroid Build Coastguard Worker  *   4. Initialization
332*38e8c45fSAndroid Build Coastguard Worker  *
333*38e8c45fSAndroid Build Coastguard Worker  *   5. For each graphic format in the previously formed list perform
334*38e8c45fSAndroid Build Coastguard Worker  *      measurements on that format and report the results.
335*38e8c45fSAndroid Build Coastguard Worker  *
336*38e8c45fSAndroid Build Coastguard Worker  *   6. Start framework
337*38e8c45fSAndroid Build Coastguard Worker  */
338*38e8c45fSAndroid Build Coastguard Worker int
main(int argc,char * argv[])339*38e8c45fSAndroid Build Coastguard Worker main(int argc, char *argv[])
340*38e8c45fSAndroid Build Coastguard Worker {
341*38e8c45fSAndroid Build Coastguard Worker     int     rv, opt;
342*38e8c45fSAndroid Build Coastguard Worker     bool    error;
343*38e8c45fSAndroid Build Coastguard Worker     string  str;
344*38e8c45fSAndroid Build Coastguard Worker     char cmd[MAXCMD];
345*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
346*38e8c45fSAndroid Build Coastguard Worker 
347*38e8c45fSAndroid Build Coastguard Worker     testSetLogCatTag(LOG_TAG);
348*38e8c45fSAndroid Build Coastguard Worker 
349*38e8c45fSAndroid Build Coastguard Worker     // Parse command line arguments
350*38e8c45fSAndroid Build Coastguard Worker     while ((opt = getopt(argc, argv, "s:v?h")) != -1) {
351*38e8c45fSAndroid Build Coastguard Worker         switch (opt) {
352*38e8c45fSAndroid Build Coastguard Worker 
353*38e8c45fSAndroid Build Coastguard Worker           case 's': // Start Dimension
354*38e8c45fSAndroid Build Coastguard Worker             // Use arguments until next starts with a dash
355*38e8c45fSAndroid Build Coastguard Worker             // or current ends with a > or ]
356*38e8c45fSAndroid Build Coastguard Worker             str = optarg;
357*38e8c45fSAndroid Build Coastguard Worker             while (optind < argc) {
358*38e8c45fSAndroid Build Coastguard Worker                 if (*argv[optind] == '-') { break; }
359*38e8c45fSAndroid Build Coastguard Worker                 char endChar = (str.length() > 1) ? str[str.length() - 1] : 0;
360*38e8c45fSAndroid Build Coastguard Worker                 if ((endChar == '>') || (endChar == ']')) { break; }
361*38e8c45fSAndroid Build Coastguard Worker                 str += " " + string(argv[optind++]);
362*38e8c45fSAndroid Build Coastguard Worker             }
363*38e8c45fSAndroid Build Coastguard Worker             {
364*38e8c45fSAndroid Build Coastguard Worker                 istringstream in(str);
365*38e8c45fSAndroid Build Coastguard Worker                 startDim = hwcTestParseDim(in, error);
366*38e8c45fSAndroid Build Coastguard Worker                 // Any parse error or characters not used by parser
367*38e8c45fSAndroid Build Coastguard Worker                 if (error
368*38e8c45fSAndroid Build Coastguard Worker                     || (((unsigned int) in.tellg() != in.str().length())
369*38e8c45fSAndroid Build Coastguard Worker                         && (in.tellg() != (streampos) -1))) {
370*38e8c45fSAndroid Build Coastguard Worker                     testPrintE("Invalid command-line specified start "
371*38e8c45fSAndroid Build Coastguard Worker                                "dimension of: %s", str.c_str());
372*38e8c45fSAndroid Build Coastguard Worker                     exit(8);
373*38e8c45fSAndroid Build Coastguard Worker                 }
374*38e8c45fSAndroid Build Coastguard Worker             }
375*38e8c45fSAndroid Build Coastguard Worker             break;
376*38e8c45fSAndroid Build Coastguard Worker 
377*38e8c45fSAndroid Build Coastguard Worker           case 'v': // Verbose
378*38e8c45fSAndroid Build Coastguard Worker             verbose = true;
379*38e8c45fSAndroid Build Coastguard Worker             break;
380*38e8c45fSAndroid Build Coastguard Worker 
381*38e8c45fSAndroid Build Coastguard Worker           case 'h': // Help
382*38e8c45fSAndroid Build Coastguard Worker           case '?':
383*38e8c45fSAndroid Build Coastguard Worker           default:
384*38e8c45fSAndroid Build Coastguard Worker             printSyntax(basename(argv[0]));
385*38e8c45fSAndroid Build Coastguard Worker             exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
386*38e8c45fSAndroid Build Coastguard Worker         }
387*38e8c45fSAndroid Build Coastguard Worker     }
388*38e8c45fSAndroid Build Coastguard Worker 
389*38e8c45fSAndroid Build Coastguard Worker     // Positional parameters
390*38e8c45fSAndroid Build Coastguard Worker     // Positional parameters provide the names of graphic formats that
391*38e8c45fSAndroid Build Coastguard Worker     // measurements are to be made on.  Measurements are made on all
392*38e8c45fSAndroid Build Coastguard Worker     // known graphic formats when no positional parameters are provided.
393*38e8c45fSAndroid Build Coastguard Worker     if (optind == argc) {
394*38e8c45fSAndroid Build Coastguard Worker         // No command-line specified graphic formats
395*38e8c45fSAndroid Build Coastguard Worker         // Add all graphic formats to the list of formats to be measured
396*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
397*38e8c45fSAndroid Build Coastguard Worker             formats.push_back(hwcTestGraphicFormat[n1].desc);
398*38e8c45fSAndroid Build Coastguard Worker         }
399*38e8c45fSAndroid Build Coastguard Worker     } else {
400*38e8c45fSAndroid Build Coastguard Worker         // Add names of command-line specified graphic formats to the
401*38e8c45fSAndroid Build Coastguard Worker         // list of formats to be tested
402*38e8c45fSAndroid Build Coastguard Worker         for (; argv[optind] != NULL; optind++) {
403*38e8c45fSAndroid Build Coastguard Worker             formats.push_back(argv[optind]);
404*38e8c45fSAndroid Build Coastguard Worker         }
405*38e8c45fSAndroid Build Coastguard Worker     }
406*38e8c45fSAndroid Build Coastguard Worker 
407*38e8c45fSAndroid Build Coastguard Worker     // Determine length of longest specified graphic format.
408*38e8c45fSAndroid Build Coastguard Worker     // This value is used for output formating
409*38e8c45fSAndroid Build Coastguard Worker     for (vector<string>::iterator it = formats.begin();
410*38e8c45fSAndroid Build Coastguard Worker          it != formats.end(); ++it) {
411*38e8c45fSAndroid Build Coastguard Worker          maxHeadingLen = max(maxHeadingLen, it->length());
412*38e8c45fSAndroid Build Coastguard Worker     }
413*38e8c45fSAndroid Build Coastguard Worker 
414*38e8c45fSAndroid Build Coastguard Worker     // Stop framework
415*38e8c45fSAndroid Build Coastguard Worker     rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
416*38e8c45fSAndroid Build Coastguard Worker     if (rv >= (signed) sizeof(cmd) - 1) {
417*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
418*38e8c45fSAndroid Build Coastguard Worker         exit(14);
419*38e8c45fSAndroid Build Coastguard Worker     }
420*38e8c45fSAndroid Build Coastguard Worker     testExecCmd(cmd);
421*38e8c45fSAndroid Build Coastguard Worker     testDelay(1.0); // TODO - needs means to query whether asynchronous stop
422*38e8c45fSAndroid Build Coastguard Worker                     // framework operation has completed.  For now, just wait
423*38e8c45fSAndroid Build Coastguard Worker                     // a long time.
424*38e8c45fSAndroid Build Coastguard Worker 
425*38e8c45fSAndroid Build Coastguard Worker     testPrintI("startDim: %s", ((string) startDim).c_str());
426*38e8c45fSAndroid Build Coastguard Worker 
427*38e8c45fSAndroid Build Coastguard Worker     init();
428*38e8c45fSAndroid Build Coastguard Worker 
429*38e8c45fSAndroid Build Coastguard Worker     // For each of the graphic formats
430*38e8c45fSAndroid Build Coastguard Worker     for (vector<string>::iterator itFormat = formats.begin();
431*38e8c45fSAndroid Build Coastguard Worker          itFormat != formats.end(); ++itFormat) {
432*38e8c45fSAndroid Build Coastguard Worker 
433*38e8c45fSAndroid Build Coastguard Worker         // Locate hwcTestLib structure that describes this format
434*38e8c45fSAndroid Build Coastguard Worker         const struct hwcTestGraphicFormat *format;
435*38e8c45fSAndroid Build Coastguard Worker         format = hwcTestGraphicFormatLookup((*itFormat).c_str());
436*38e8c45fSAndroid Build Coastguard Worker         if (format == NULL) {
437*38e8c45fSAndroid Build Coastguard Worker             testPrintE("Unknown graphic format of: %s", (*itFormat).c_str());
438*38e8c45fSAndroid Build Coastguard Worker             exit(1);
439*38e8c45fSAndroid Build Coastguard Worker         }
440*38e8c45fSAndroid Build Coastguard Worker 
441*38e8c45fSAndroid Build Coastguard Worker         // Display format header
442*38e8c45fSAndroid Build Coastguard Worker         testPrintI("format: %s", format->desc);
443*38e8c45fSAndroid Build Coastguard Worker 
444*38e8c45fSAndroid Build Coastguard Worker         // Create area to hold the measurements
445*38e8c45fSAndroid Build Coastguard Worker         struct meas meas;
446*38e8c45fSAndroid Build Coastguard Worker         struct meas *measPtr;
447*38e8c45fSAndroid Build Coastguard Worker         meas.format = format->format;
448*38e8c45fSAndroid Build Coastguard Worker         measurements.push_back(meas);
449*38e8c45fSAndroid Build Coastguard Worker         measPtr = &measurements[measurements.size() - 1];
450*38e8c45fSAndroid Build Coastguard Worker 
451*38e8c45fSAndroid Build Coastguard Worker         // Start dimension num overlays
452*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format->format, startDim);
453*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
454*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
455*38e8c45fSAndroid Build Coastguard Worker         measPtr->startDimOverlays = numOverlays(rectList);
456*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  startDimOverlays: %u", measPtr->startDimOverlays);
457*38e8c45fSAndroid Build Coastguard Worker 
458*38e8c45fSAndroid Build Coastguard Worker         // Skip the rest of the measurements, when the start dimension
459*38e8c45fSAndroid Build Coastguard Worker         // doesn't produce an overlay
460*38e8c45fSAndroid Build Coastguard Worker         if (measPtr->startDimOverlays == 0) { continue; }
461*38e8c45fSAndroid Build Coastguard Worker 
462*38e8c45fSAndroid Build Coastguard Worker         // Max Overlays
463*38e8c45fSAndroid Build Coastguard Worker         measPtr->maxNonOverlapping = maxOverlays(format->format, false);
464*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  max nonOverlapping overlays: %s%u",
465*38e8c45fSAndroid Build Coastguard Worker                    (measPtr->maxNonOverlapping == searchLimits.numOverlays)
466*38e8c45fSAndroid Build Coastguard Worker                        ? ">= " : "",
467*38e8c45fSAndroid Build Coastguard Worker                    measPtr->maxNonOverlapping);
468*38e8c45fSAndroid Build Coastguard Worker         measPtr->maxOverlapping = maxOverlays(format->format, true);
469*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  max Overlapping overlays: %s%u",
470*38e8c45fSAndroid Build Coastguard Worker                    (measPtr->maxOverlapping == searchLimits.numOverlays)
471*38e8c45fSAndroid Build Coastguard Worker                        ? ">= " : "",
472*38e8c45fSAndroid Build Coastguard Worker                    measPtr->maxOverlapping);
473*38e8c45fSAndroid Build Coastguard Worker 
474*38e8c45fSAndroid Build Coastguard Worker         // Transforms and blends
475*38e8c45fSAndroid Build Coastguard Worker         measPtr->transforms = supportedTransforms(format->format);
476*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  transforms: %s",
477*38e8c45fSAndroid Build Coastguard Worker                    transformList2str(measPtr->transforms).c_str());
478*38e8c45fSAndroid Build Coastguard Worker         measPtr->blends = supportedBlends(format->format);
479*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  blends: %s",
480*38e8c45fSAndroid Build Coastguard Worker                    blendList2str(measPtr->blends).c_str());
481*38e8c45fSAndroid Build Coastguard Worker 
482*38e8c45fSAndroid Build Coastguard Worker         // Display frame measurements
483*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.minWidth = dfMinWidth(format->format);
484*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMinWidth: %u", measPtr->df.minWidth);
485*38e8c45fSAndroid Build Coastguard Worker 
486*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.minHeight = dfMinHeight(format->format);
487*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMinHeight: %u", measPtr->df.minHeight);
488*38e8c45fSAndroid Build Coastguard Worker 
489*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.maxWidth = dfMaxWidth(format->format);
490*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMaxWidth: %u", measPtr->df.maxWidth);
491*38e8c45fSAndroid Build Coastguard Worker 
492*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.maxHeight = dfMaxHeight(format->format);
493*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMaxHeight: %u", measPtr->df.maxHeight);
494*38e8c45fSAndroid Build Coastguard Worker 
495*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.minDim = dfMinDim(format->format);
496*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMinDim: %s", ((string) measPtr->df.minDim).c_str());
497*38e8c45fSAndroid Build Coastguard Worker 
498*38e8c45fSAndroid Build Coastguard Worker         measPtr->df.maxDim = dfMaxDim(format->format);
499*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  dfMaxDim: %s", ((string) measPtr->df.maxDim).c_str());
500*38e8c45fSAndroid Build Coastguard Worker 
501*38e8c45fSAndroid Build Coastguard Worker         // Source crop measurements
502*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.minWidth = scMinWidth(format->format, measPtr->df.minDim);
503*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMinWidth: %u", measPtr->sc.minWidth);
504*38e8c45fSAndroid Build Coastguard Worker 
505*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.minHeight = scMinHeight(format->format, measPtr->df.minDim);
506*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMinHeight: %u", measPtr->sc.minHeight);
507*38e8c45fSAndroid Build Coastguard Worker 
508*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.maxWidth = scMaxWidth(format->format, measPtr->df.maxDim);
509*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMaxWidth: %s%u", (measPtr->sc.maxWidth
510*38e8c45fSAndroid Build Coastguard Worker                    == searchLimits.sourceCrop.width()) ? ">= " : "",
511*38e8c45fSAndroid Build Coastguard Worker                    measPtr->sc.maxWidth);
512*38e8c45fSAndroid Build Coastguard Worker 
513*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.maxHeight = scMaxHeight(format->format, measPtr->df.maxDim);
514*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMaxHeight: %s%u", (measPtr->sc.maxHeight
515*38e8c45fSAndroid Build Coastguard Worker                    == searchLimits.sourceCrop.height()) ? ">= " : "",
516*38e8c45fSAndroid Build Coastguard Worker                    measPtr->sc.maxHeight);
517*38e8c45fSAndroid Build Coastguard Worker 
518*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.minDim = scMinDim(format->format, measPtr->df.minDim);
519*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMinDim: %s", ((string) measPtr->sc.minDim).c_str());
520*38e8c45fSAndroid Build Coastguard Worker 
521*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.maxDim = scMaxDim(format->format, measPtr->df.maxDim);
522*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scMaxDim: %s%s", ((measPtr->sc.maxDim.width()
523*38e8c45fSAndroid Build Coastguard Worker                          >= searchLimits.sourceCrop.width())
524*38e8c45fSAndroid Build Coastguard Worker                          || (measPtr->sc.maxDim.width() >=
525*38e8c45fSAndroid Build Coastguard Worker                          searchLimits.sourceCrop.height())) ? ">= " : "",
526*38e8c45fSAndroid Build Coastguard Worker                    ((string) measPtr->sc.maxDim).c_str());
527*38e8c45fSAndroid Build Coastguard Worker 
528*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.hScale = scHScale(format->format,
529*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->df.minDim, measPtr->df.maxDim,
530*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.minDim, measPtr->sc.maxDim,
531*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.hScaleBestDf,
532*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.hScaleBestSc);
533*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scHScale: %s%f",
534*38e8c45fSAndroid Build Coastguard Worker                    (measPtr->sc.hScale
535*38e8c45fSAndroid Build Coastguard Worker                        >= Rational(searchLimits.sourceCrop.width(),
536*38e8c45fSAndroid Build Coastguard Worker                                    measPtr->df.minDim.width())) ? ">= " : "",
537*38e8c45fSAndroid Build Coastguard Worker                    (double) measPtr->sc.hScale);
538*38e8c45fSAndroid Build Coastguard Worker         testPrintI("    HScale Best Display Frame: %s",
539*38e8c45fSAndroid Build Coastguard Worker                    ((string) measPtr->sc.hScaleBestDf).c_str());
540*38e8c45fSAndroid Build Coastguard Worker         testPrintI("    HScale Best Source Crop: %s",
541*38e8c45fSAndroid Build Coastguard Worker                    ((string) measPtr->sc.hScaleBestSc).c_str());
542*38e8c45fSAndroid Build Coastguard Worker 
543*38e8c45fSAndroid Build Coastguard Worker         measPtr->sc.vScale = scVScale(format->format,
544*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->df.minDim, measPtr->df.maxDim,
545*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.minDim, measPtr->sc.maxDim,
546*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.vScaleBestDf,
547*38e8c45fSAndroid Build Coastguard Worker                                       measPtr->sc.vScaleBestSc);
548*38e8c45fSAndroid Build Coastguard Worker         testPrintI("  scVScale: %s%f",
549*38e8c45fSAndroid Build Coastguard Worker                    (measPtr->sc.vScale
550*38e8c45fSAndroid Build Coastguard Worker                        >= Rational(searchLimits.sourceCrop.height(),
551*38e8c45fSAndroid Build Coastguard Worker                                    measPtr->df.minDim.height())) ? ">= " : "",
552*38e8c45fSAndroid Build Coastguard Worker                    (double) measPtr->sc.vScale);
553*38e8c45fSAndroid Build Coastguard Worker         testPrintI("    VScale Best Display Frame: %s",
554*38e8c45fSAndroid Build Coastguard Worker                    ((string) measPtr->sc.vScaleBestDf).c_str());
555*38e8c45fSAndroid Build Coastguard Worker         testPrintI("    VScale Best Source Crop: %s",
556*38e8c45fSAndroid Build Coastguard Worker                    ((string) measPtr->sc.vScaleBestSc).c_str());
557*38e8c45fSAndroid Build Coastguard Worker 
558*38e8c45fSAndroid Build Coastguard Worker         // Overlap two graphic formats and different blends
559*38e8c45fSAndroid Build Coastguard Worker         // Results displayed after all overlap measurments with
560*38e8c45fSAndroid Build Coastguard Worker         // current format in the foreground
561*38e8c45fSAndroid Build Coastguard Worker         // TODO: make measurments with background blend other than
562*38e8c45fSAndroid Build Coastguard Worker         //       none.  All of these measurements are done with a
563*38e8c45fSAndroid Build Coastguard Worker         //       background blend of HWC_BLENDING_NONE, with the
564*38e8c45fSAndroid Build Coastguard Worker         //       blend type of the foregound being varied.
565*38e8c45fSAndroid Build Coastguard Worker         uint32_t foregroundFormat = format->format;
566*38e8c45fSAndroid Build Coastguard Worker         for (vector<string>::iterator it = formats.begin();
567*38e8c45fSAndroid Build Coastguard Worker              it != formats.end(); ++it) {
568*38e8c45fSAndroid Build Coastguard Worker             uint32_t num;
569*38e8c45fSAndroid Build Coastguard Worker 
570*38e8c45fSAndroid Build Coastguard Worker             const struct hwcTestGraphicFormat *backgroundFormatPtr
571*38e8c45fSAndroid Build Coastguard Worker                 = hwcTestGraphicFormatLookup((*it).c_str());
572*38e8c45fSAndroid Build Coastguard Worker             uint32_t backgroundFormat = backgroundFormatPtr->format;
573*38e8c45fSAndroid Build Coastguard Worker 
574*38e8c45fSAndroid Build Coastguard Worker             num = numOverlapping(backgroundFormat, foregroundFormat,
575*38e8c45fSAndroid Build Coastguard Worker                                  HWC_BLENDING_NONE, HWC_BLENDING_NONE);
576*38e8c45fSAndroid Build Coastguard Worker             measPtr->overlapBlendNone.push_back(num);
577*38e8c45fSAndroid Build Coastguard Worker 
578*38e8c45fSAndroid Build Coastguard Worker             num = numOverlapping(backgroundFormat, foregroundFormat,
579*38e8c45fSAndroid Build Coastguard Worker                                  HWC_BLENDING_NONE, HWC_BLENDING_PREMULT);
580*38e8c45fSAndroid Build Coastguard Worker             measPtr->overlapBlendPremult.push_back(num);
581*38e8c45fSAndroid Build Coastguard Worker 
582*38e8c45fSAndroid Build Coastguard Worker             num = numOverlapping(backgroundFormat, foregroundFormat,
583*38e8c45fSAndroid Build Coastguard Worker                                  HWC_BLENDING_NONE, HWC_BLENDING_COVERAGE);
584*38e8c45fSAndroid Build Coastguard Worker             measPtr->overlapBlendCoverage.push_back(num);
585*38e8c45fSAndroid Build Coastguard Worker         }
586*38e8c45fSAndroid Build Coastguard Worker 
587*38e8c45fSAndroid Build Coastguard Worker     }
588*38e8c45fSAndroid Build Coastguard Worker 
589*38e8c45fSAndroid Build Coastguard Worker     // Display overlap results
590*38e8c45fSAndroid Build Coastguard Worker     size_t indent = 2;
591*38e8c45fSAndroid Build Coastguard Worker     testPrintI("overlapping blend: none");
592*38e8c45fSAndroid Build Coastguard Worker     printFormatHeadings(indent);
593*38e8c45fSAndroid Build Coastguard Worker     for (vector<string>::iterator it = formats.begin();
594*38e8c45fSAndroid Build Coastguard Worker          it != formats.end(); ++it) {
595*38e8c45fSAndroid Build Coastguard Worker         printOverlapLine(indent, *it, measurements[it
596*38e8c45fSAndroid Build Coastguard Worker                          - formats.begin()].overlapBlendNone);
597*38e8c45fSAndroid Build Coastguard Worker     }
598*38e8c45fSAndroid Build Coastguard Worker     testPrintI("");
599*38e8c45fSAndroid Build Coastguard Worker 
600*38e8c45fSAndroid Build Coastguard Worker     testPrintI("overlapping blend: premult");
601*38e8c45fSAndroid Build Coastguard Worker     printFormatHeadings(indent);
602*38e8c45fSAndroid Build Coastguard Worker     for (vector<string>::iterator it = formats.begin();
603*38e8c45fSAndroid Build Coastguard Worker          it != formats.end(); ++it) {
604*38e8c45fSAndroid Build Coastguard Worker         printOverlapLine(indent, *it, measurements[it
605*38e8c45fSAndroid Build Coastguard Worker                          - formats.begin()].overlapBlendPremult);
606*38e8c45fSAndroid Build Coastguard Worker     }
607*38e8c45fSAndroid Build Coastguard Worker     testPrintI("");
608*38e8c45fSAndroid Build Coastguard Worker 
609*38e8c45fSAndroid Build Coastguard Worker     testPrintI("overlapping blend: coverage");
610*38e8c45fSAndroid Build Coastguard Worker     printFormatHeadings(indent);
611*38e8c45fSAndroid Build Coastguard Worker     for (vector<string>::iterator it = formats.begin();
612*38e8c45fSAndroid Build Coastguard Worker          it != formats.end(); ++it) {
613*38e8c45fSAndroid Build Coastguard Worker         printOverlapLine(indent, *it, measurements[it
614*38e8c45fSAndroid Build Coastguard Worker                          - formats.begin()].overlapBlendCoverage);
615*38e8c45fSAndroid Build Coastguard Worker     }
616*38e8c45fSAndroid Build Coastguard Worker     testPrintI("");
617*38e8c45fSAndroid Build Coastguard Worker 
618*38e8c45fSAndroid Build Coastguard Worker     // Start framework
619*38e8c45fSAndroid Build Coastguard Worker     rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
620*38e8c45fSAndroid Build Coastguard Worker     if (rv >= (signed) sizeof(cmd) - 1) {
621*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
622*38e8c45fSAndroid Build Coastguard Worker         exit(21);
623*38e8c45fSAndroid Build Coastguard Worker     }
624*38e8c45fSAndroid Build Coastguard Worker     testExecCmd(cmd);
625*38e8c45fSAndroid Build Coastguard Worker 
626*38e8c45fSAndroid Build Coastguard Worker     return 0;
627*38e8c45fSAndroid Build Coastguard Worker }
628*38e8c45fSAndroid Build Coastguard Worker 
629*38e8c45fSAndroid Build Coastguard Worker // Determine the maximum number of overlays that are all of the same format
630*38e8c45fSAndroid Build Coastguard Worker // that the HWC will commit to.  If allowOverlap is true, then the rectangles
631*38e8c45fSAndroid Build Coastguard Worker // are laid out on a diagonal starting from the upper left corner.  With
632*38e8c45fSAndroid Build Coastguard Worker // each rectangle adjust one pixel to the right and one pixel down.
633*38e8c45fSAndroid Build Coastguard Worker // When allowOverlap is false, the rectangles are tiled in column major
634*38e8c45fSAndroid Build Coastguard Worker // order.  Note, column major ordering is used so that the initial rectangles
635*38e8c45fSAndroid Build Coastguard Worker // are all on different horizontal scan rows.  It is common that hardware
636*38e8c45fSAndroid Build Coastguard Worker // has limits on the number of objects it can handle on any single row.
maxOverlays(uint32_t format,bool allowOverlap)637*38e8c45fSAndroid Build Coastguard Worker uint32_t maxOverlays(uint32_t format, bool allowOverlap)
638*38e8c45fSAndroid Build Coastguard Worker {
639*38e8c45fSAndroid Build Coastguard Worker     unsigned int max = 0;
640*38e8c45fSAndroid Build Coastguard Worker 
641*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int numRects = 1; numRects <= searchLimits.numOverlays;
642*38e8c45fSAndroid Build Coastguard Worker          numRects++) {
643*38e8c45fSAndroid Build Coastguard Worker         list<Rectangle> rectList;
644*38e8c45fSAndroid Build Coastguard Worker 
645*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int x = 0;
646*38e8c45fSAndroid Build Coastguard Worker              (x + startDim.width()) < (unsigned int) width;
647*38e8c45fSAndroid Build Coastguard Worker              x += (allowOverlap) ? 1 : startDim.width()) {
648*38e8c45fSAndroid Build Coastguard Worker             for (unsigned int y = 0;
649*38e8c45fSAndroid Build Coastguard Worker                  (y + startDim.height()) < (unsigned int) height;
650*38e8c45fSAndroid Build Coastguard Worker                  y += (allowOverlap) ? 1 : startDim.height()) {
651*38e8c45fSAndroid Build Coastguard Worker                 Rectangle rect(format, startDim, startDim);
652*38e8c45fSAndroid Build Coastguard Worker                 rect.displayFrame.left = x;
653*38e8c45fSAndroid Build Coastguard Worker                 rect.displayFrame.top = y;
654*38e8c45fSAndroid Build Coastguard Worker                 rect.displayFrame.right = x + startDim.width();
655*38e8c45fSAndroid Build Coastguard Worker                 rect.displayFrame.bottom = y + startDim.height();
656*38e8c45fSAndroid Build Coastguard Worker 
657*38e8c45fSAndroid Build Coastguard Worker                 rectList.push_back(rect);
658*38e8c45fSAndroid Build Coastguard Worker 
659*38e8c45fSAndroid Build Coastguard Worker                 if (rectList.size() >= numRects) { break; }
660*38e8c45fSAndroid Build Coastguard Worker             }
661*38e8c45fSAndroid Build Coastguard Worker             if (rectList.size() >= numRects) { break; }
662*38e8c45fSAndroid Build Coastguard Worker         }
663*38e8c45fSAndroid Build Coastguard Worker 
664*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
665*38e8c45fSAndroid Build Coastguard Worker         if (num > max) { max = num; }
666*38e8c45fSAndroid Build Coastguard Worker     }
667*38e8c45fSAndroid Build Coastguard Worker 
668*38e8c45fSAndroid Build Coastguard Worker     return max;
669*38e8c45fSAndroid Build Coastguard Worker }
670*38e8c45fSAndroid Build Coastguard Worker 
671*38e8c45fSAndroid Build Coastguard Worker // Measures what transforms (i.e. flip horizontal, rotate 180) are
672*38e8c45fSAndroid Build Coastguard Worker // supported by the specified format
supportedTransforms(uint32_t format)673*38e8c45fSAndroid Build Coastguard Worker list<uint32_t> supportedTransforms(uint32_t format)
674*38e8c45fSAndroid Build Coastguard Worker {
675*38e8c45fSAndroid Build Coastguard Worker     list<uint32_t> rv;
676*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
677*38e8c45fSAndroid Build Coastguard Worker     Rectangle rect(format, startDim);
678*38e8c45fSAndroid Build Coastguard Worker 
679*38e8c45fSAndroid Build Coastguard Worker     // For each of the transform types
680*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
681*38e8c45fSAndroid Build Coastguard Worker         unsigned int id = transformType[idx].id;
682*38e8c45fSAndroid Build Coastguard Worker 
683*38e8c45fSAndroid Build Coastguard Worker         rect.transform = id;
684*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
685*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
686*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
687*38e8c45fSAndroid Build Coastguard Worker 
688*38e8c45fSAndroid Build Coastguard Worker         if (num == 1) {
689*38e8c45fSAndroid Build Coastguard Worker             rv.push_back(id);
690*38e8c45fSAndroid Build Coastguard Worker         }
691*38e8c45fSAndroid Build Coastguard Worker     }
692*38e8c45fSAndroid Build Coastguard Worker 
693*38e8c45fSAndroid Build Coastguard Worker     return rv;
694*38e8c45fSAndroid Build Coastguard Worker }
695*38e8c45fSAndroid Build Coastguard Worker 
696*38e8c45fSAndroid Build Coastguard Worker // Determines which types of blends (i.e. none, premult, coverage) are
697*38e8c45fSAndroid Build Coastguard Worker // supported by the specified format
supportedBlends(uint32_t format)698*38e8c45fSAndroid Build Coastguard Worker list<uint32_t> supportedBlends(uint32_t format)
699*38e8c45fSAndroid Build Coastguard Worker {
700*38e8c45fSAndroid Build Coastguard Worker     list<uint32_t> rv;
701*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
702*38e8c45fSAndroid Build Coastguard Worker     Rectangle rect(format, startDim);
703*38e8c45fSAndroid Build Coastguard Worker 
704*38e8c45fSAndroid Build Coastguard Worker     // For each of the blend types
705*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
706*38e8c45fSAndroid Build Coastguard Worker         unsigned int id = blendType[idx].id;
707*38e8c45fSAndroid Build Coastguard Worker 
708*38e8c45fSAndroid Build Coastguard Worker         rect.blend = id;
709*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
710*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
711*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
712*38e8c45fSAndroid Build Coastguard Worker 
713*38e8c45fSAndroid Build Coastguard Worker         if (num == 1) {
714*38e8c45fSAndroid Build Coastguard Worker             rv.push_back(id);
715*38e8c45fSAndroid Build Coastguard Worker         }
716*38e8c45fSAndroid Build Coastguard Worker     }
717*38e8c45fSAndroid Build Coastguard Worker 
718*38e8c45fSAndroid Build Coastguard Worker     return rv;
719*38e8c45fSAndroid Build Coastguard Worker }
720*38e8c45fSAndroid Build Coastguard Worker 
721*38e8c45fSAndroid Build Coastguard Worker // Determines the minimum width of any display frame of the given format
722*38e8c45fSAndroid Build Coastguard Worker // that the HWC will commit to.
dfMinWidth(uint32_t format)723*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMinWidth(uint32_t format)
724*38e8c45fSAndroid Build Coastguard Worker {
725*38e8c45fSAndroid Build Coastguard Worker     uint32_t w;
726*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
727*38e8c45fSAndroid Build Coastguard Worker 
728*38e8c45fSAndroid Build Coastguard Worker     for (w = 1; w <= startDim.width(); w++) {
729*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim dim(w, startDim.height());
730*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dim);
731*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
732*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
733*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
734*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
735*38e8c45fSAndroid Build Coastguard Worker             return w;
736*38e8c45fSAndroid Build Coastguard Worker         }
737*38e8c45fSAndroid Build Coastguard Worker     }
738*38e8c45fSAndroid Build Coastguard Worker     if (w > startDim.width()) {
739*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Failed to locate display frame min width");
740*38e8c45fSAndroid Build Coastguard Worker         exit(33);
741*38e8c45fSAndroid Build Coastguard Worker     }
742*38e8c45fSAndroid Build Coastguard Worker 
743*38e8c45fSAndroid Build Coastguard Worker     return w;
744*38e8c45fSAndroid Build Coastguard Worker }
745*38e8c45fSAndroid Build Coastguard Worker 
746*38e8c45fSAndroid Build Coastguard Worker // Display frame minimum height
dfMinHeight(uint32_t format)747*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMinHeight(uint32_t format)
748*38e8c45fSAndroid Build Coastguard Worker {
749*38e8c45fSAndroid Build Coastguard Worker     uint32_t h;
750*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
751*38e8c45fSAndroid Build Coastguard Worker 
752*38e8c45fSAndroid Build Coastguard Worker     for (h = 1; h <= startDim.height(); h++) {
753*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim dim(startDim.width(), h);
754*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dim);
755*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
756*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
757*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
758*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
759*38e8c45fSAndroid Build Coastguard Worker             return h;
760*38e8c45fSAndroid Build Coastguard Worker         }
761*38e8c45fSAndroid Build Coastguard Worker     }
762*38e8c45fSAndroid Build Coastguard Worker     if (h > startDim.height()) {
763*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Failed to locate display frame min height");
764*38e8c45fSAndroid Build Coastguard Worker         exit(34);
765*38e8c45fSAndroid Build Coastguard Worker     }
766*38e8c45fSAndroid Build Coastguard Worker 
767*38e8c45fSAndroid Build Coastguard Worker     return h;
768*38e8c45fSAndroid Build Coastguard Worker }
769*38e8c45fSAndroid Build Coastguard Worker 
770*38e8c45fSAndroid Build Coastguard Worker // Display frame maximum width
dfMaxWidth(uint32_t format)771*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMaxWidth(uint32_t format)
772*38e8c45fSAndroid Build Coastguard Worker {
773*38e8c45fSAndroid Build Coastguard Worker     uint32_t w;
774*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
775*38e8c45fSAndroid Build Coastguard Worker 
776*38e8c45fSAndroid Build Coastguard Worker     for (w = width; w >= startDim.width(); w--) {
777*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim dim(w, startDim.height());
778*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dim);
779*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
780*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
781*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
782*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
783*38e8c45fSAndroid Build Coastguard Worker             return w;
784*38e8c45fSAndroid Build Coastguard Worker         }
785*38e8c45fSAndroid Build Coastguard Worker     }
786*38e8c45fSAndroid Build Coastguard Worker     if (w < startDim.width()) {
787*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Failed to locate display frame max width");
788*38e8c45fSAndroid Build Coastguard Worker         exit(35);
789*38e8c45fSAndroid Build Coastguard Worker     }
790*38e8c45fSAndroid Build Coastguard Worker 
791*38e8c45fSAndroid Build Coastguard Worker     return w;
792*38e8c45fSAndroid Build Coastguard Worker }
793*38e8c45fSAndroid Build Coastguard Worker 
794*38e8c45fSAndroid Build Coastguard Worker // Display frame maximum height
dfMaxHeight(uint32_t format)795*38e8c45fSAndroid Build Coastguard Worker uint32_t dfMaxHeight(uint32_t format)
796*38e8c45fSAndroid Build Coastguard Worker {
797*38e8c45fSAndroid Build Coastguard Worker     uint32_t h;
798*38e8c45fSAndroid Build Coastguard Worker 
799*38e8c45fSAndroid Build Coastguard Worker     for (h = height; h >= startDim.height(); h--) {
800*38e8c45fSAndroid Build Coastguard Worker         HwcTestDim dim(startDim.width(), h);
801*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dim);
802*38e8c45fSAndroid Build Coastguard Worker         list<Rectangle> rectList;
803*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
804*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
805*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
806*38e8c45fSAndroid Build Coastguard Worker             return h;
807*38e8c45fSAndroid Build Coastguard Worker         }
808*38e8c45fSAndroid Build Coastguard Worker     }
809*38e8c45fSAndroid Build Coastguard Worker     if (h < startDim.height()) {
810*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Failed to locate display frame max height");
811*38e8c45fSAndroid Build Coastguard Worker         exit(36);
812*38e8c45fSAndroid Build Coastguard Worker     }
813*38e8c45fSAndroid Build Coastguard Worker 
814*38e8c45fSAndroid Build Coastguard Worker     return h;
815*38e8c45fSAndroid Build Coastguard Worker }
816*38e8c45fSAndroid Build Coastguard Worker 
817*38e8c45fSAndroid Build Coastguard Worker // Determine the minimum number of pixels that the HWC will ever commit to.
818*38e8c45fSAndroid Build Coastguard Worker // Note, this might be different that dfMinWidth * dfMinHeight, in that this
819*38e8c45fSAndroid Build Coastguard Worker // function adjusts both the width and height from the starting dimension.
dfMinDim(uint32_t format)820*38e8c45fSAndroid Build Coastguard Worker HwcTestDim dfMinDim(uint32_t format)
821*38e8c45fSAndroid Build Coastguard Worker {
822*38e8c45fSAndroid Build Coastguard Worker     uint64_t bestMinPixels = 0;
823*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim bestDim;
824*38e8c45fSAndroid Build Coastguard Worker     bool bestSet = false; // True when value has been assigned to
825*38e8c45fSAndroid Build Coastguard Worker                           // bestMinPixels and bestDim
826*38e8c45fSAndroid Build Coastguard Worker 
827*38e8c45fSAndroid Build Coastguard Worker     bool origVerbose = verbose;  // Temporarily turn off verbose
828*38e8c45fSAndroid Build Coastguard Worker     verbose = false;
829*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t w = 1; w <= startDim.width(); w++) {
830*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t h = 1; h <= startDim.height(); h++) {
831*38e8c45fSAndroid Build Coastguard Worker             if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
832*38e8c45fSAndroid Build Coastguard Worker                 break;
833*38e8c45fSAndroid Build Coastguard Worker             }
834*38e8c45fSAndroid Build Coastguard Worker 
835*38e8c45fSAndroid Build Coastguard Worker             HwcTestDim dim(w, h);
836*38e8c45fSAndroid Build Coastguard Worker             Rectangle rect(format, dim);
837*38e8c45fSAndroid Build Coastguard Worker             list<Rectangle> rectList;
838*38e8c45fSAndroid Build Coastguard Worker             rectList.push_back(rect);
839*38e8c45fSAndroid Build Coastguard Worker             uint32_t num = numOverlays(rectList);
840*38e8c45fSAndroid Build Coastguard Worker             if (num > 0) {
841*38e8c45fSAndroid Build Coastguard Worker                 uint64_t pixels = dim.width() * dim.height();
842*38e8c45fSAndroid Build Coastguard Worker                 if (!bestSet || (pixels < bestMinPixels)) {
843*38e8c45fSAndroid Build Coastguard Worker                     bestMinPixels = pixels;
844*38e8c45fSAndroid Build Coastguard Worker                     bestDim = dim;
845*38e8c45fSAndroid Build Coastguard Worker                     bestSet = true;
846*38e8c45fSAndroid Build Coastguard Worker                 }
847*38e8c45fSAndroid Build Coastguard Worker             }
848*38e8c45fSAndroid Build Coastguard Worker         }
849*38e8c45fSAndroid Build Coastguard Worker     }
850*38e8c45fSAndroid Build Coastguard Worker     verbose = origVerbose;
851*38e8c45fSAndroid Build Coastguard Worker 
852*38e8c45fSAndroid Build Coastguard Worker     if (!bestSet) {
853*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unable to locate display frame min dimension");
854*38e8c45fSAndroid Build Coastguard Worker         exit(20);
855*38e8c45fSAndroid Build Coastguard Worker     }
856*38e8c45fSAndroid Build Coastguard Worker 
857*38e8c45fSAndroid Build Coastguard Worker     return bestDim;
858*38e8c45fSAndroid Build Coastguard Worker }
859*38e8c45fSAndroid Build Coastguard Worker 
860*38e8c45fSAndroid Build Coastguard Worker // Display frame maximum dimension
dfMaxDim(uint32_t format)861*38e8c45fSAndroid Build Coastguard Worker HwcTestDim dfMaxDim(uint32_t format)
862*38e8c45fSAndroid Build Coastguard Worker {
863*38e8c45fSAndroid Build Coastguard Worker     uint64_t bestMaxPixels = 0;
864*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim bestDim;
865*38e8c45fSAndroid Build Coastguard Worker     bool bestSet = false; // True when value has been assigned to
866*38e8c45fSAndroid Build Coastguard Worker                           // bestMaxPixels and bestDim;
867*38e8c45fSAndroid Build Coastguard Worker 
868*38e8c45fSAndroid Build Coastguard Worker     // Potentially increase benchmark performance by first checking
869*38e8c45fSAndroid Build Coastguard Worker     // for the common case of supporting a full display frame.
870*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim dim(width, height);
871*38e8c45fSAndroid Build Coastguard Worker     Rectangle rect(format, dim);
872*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
873*38e8c45fSAndroid Build Coastguard Worker     rectList.push_back(rect);
874*38e8c45fSAndroid Build Coastguard Worker     uint32_t num = numOverlays(rectList);
875*38e8c45fSAndroid Build Coastguard Worker     if (num == 1) { return dim; }
876*38e8c45fSAndroid Build Coastguard Worker 
877*38e8c45fSAndroid Build Coastguard Worker     // TODO: Use a binary search
878*38e8c45fSAndroid Build Coastguard Worker     bool origVerbose = verbose;  // Temporarily turn off verbose
879*38e8c45fSAndroid Build Coastguard Worker     verbose = false;
880*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t w = startDim.width(); w <= (uint32_t) width; w++) {
881*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t h = startDim.height(); h <= (uint32_t) height; h++) {
882*38e8c45fSAndroid Build Coastguard Worker             if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }
883*38e8c45fSAndroid Build Coastguard Worker 
884*38e8c45fSAndroid Build Coastguard Worker             HwcTestDim dim(w, h);
885*38e8c45fSAndroid Build Coastguard Worker             Rectangle rect(format, dim);
886*38e8c45fSAndroid Build Coastguard Worker             list<Rectangle> rectList;
887*38e8c45fSAndroid Build Coastguard Worker             rectList.push_back(rect);
888*38e8c45fSAndroid Build Coastguard Worker             uint32_t num = numOverlays(rectList);
889*38e8c45fSAndroid Build Coastguard Worker             if (num > 0) {
890*38e8c45fSAndroid Build Coastguard Worker                 uint64_t pixels = dim.width() * dim.height();
891*38e8c45fSAndroid Build Coastguard Worker                 if (!bestSet || (pixels > bestMaxPixels)) {
892*38e8c45fSAndroid Build Coastguard Worker                     bestMaxPixels = pixels;
893*38e8c45fSAndroid Build Coastguard Worker                     bestDim = dim;
894*38e8c45fSAndroid Build Coastguard Worker                     bestSet = true;
895*38e8c45fSAndroid Build Coastguard Worker                 }
896*38e8c45fSAndroid Build Coastguard Worker             }
897*38e8c45fSAndroid Build Coastguard Worker         }
898*38e8c45fSAndroid Build Coastguard Worker     }
899*38e8c45fSAndroid Build Coastguard Worker     verbose = origVerbose;
900*38e8c45fSAndroid Build Coastguard Worker 
901*38e8c45fSAndroid Build Coastguard Worker     if (!bestSet) {
902*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unable to locate display frame max dimension");
903*38e8c45fSAndroid Build Coastguard Worker         exit(21);
904*38e8c45fSAndroid Build Coastguard Worker     }
905*38e8c45fSAndroid Build Coastguard Worker 
906*38e8c45fSAndroid Build Coastguard Worker     return bestDim;
907*38e8c45fSAndroid Build Coastguard Worker }
908*38e8c45fSAndroid Build Coastguard Worker 
909*38e8c45fSAndroid Build Coastguard Worker // Source crop minimum width
scMinWidth(uint32_t format,const HwcTestDim & dfDim)910*38e8c45fSAndroid Build Coastguard Worker uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim)
911*38e8c45fSAndroid Build Coastguard Worker {
912*38e8c45fSAndroid Build Coastguard Worker     uint32_t w;
913*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
914*38e8c45fSAndroid Build Coastguard Worker 
915*38e8c45fSAndroid Build Coastguard Worker     // Source crop frame min width
916*38e8c45fSAndroid Build Coastguard Worker     for (w = 1; w <= dfDim.width(); w++) {
917*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
918*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
919*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
920*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
921*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
922*38e8c45fSAndroid Build Coastguard Worker             return w;
923*38e8c45fSAndroid Build Coastguard Worker         }
924*38e8c45fSAndroid Build Coastguard Worker     }
925*38e8c45fSAndroid Build Coastguard Worker     testPrintE("Failed to locate source crop min width");
926*38e8c45fSAndroid Build Coastguard Worker     exit(35);
927*38e8c45fSAndroid Build Coastguard Worker }
928*38e8c45fSAndroid Build Coastguard Worker 
929*38e8c45fSAndroid Build Coastguard Worker // Source crop minimum height
scMinHeight(uint32_t format,const HwcTestDim & dfDim)930*38e8c45fSAndroid Build Coastguard Worker uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim)
931*38e8c45fSAndroid Build Coastguard Worker {
932*38e8c45fSAndroid Build Coastguard Worker     uint32_t h;
933*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
934*38e8c45fSAndroid Build Coastguard Worker 
935*38e8c45fSAndroid Build Coastguard Worker     for (h = 1; h <= dfDim.height(); h++) {
936*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
937*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
938*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
939*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
940*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
941*38e8c45fSAndroid Build Coastguard Worker             return h;
942*38e8c45fSAndroid Build Coastguard Worker         }
943*38e8c45fSAndroid Build Coastguard Worker     }
944*38e8c45fSAndroid Build Coastguard Worker     testPrintE("Failed to locate source crop min height");
945*38e8c45fSAndroid Build Coastguard Worker     exit(36);
946*38e8c45fSAndroid Build Coastguard Worker }
947*38e8c45fSAndroid Build Coastguard Worker 
948*38e8c45fSAndroid Build Coastguard Worker // Source crop maximum width
scMaxWidth(uint32_t format,const HwcTestDim & dfDim)949*38e8c45fSAndroid Build Coastguard Worker uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim)
950*38e8c45fSAndroid Build Coastguard Worker {
951*38e8c45fSAndroid Build Coastguard Worker     uint32_t w;
952*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
953*38e8c45fSAndroid Build Coastguard Worker 
954*38e8c45fSAndroid Build Coastguard Worker     for (w = searchLimits.sourceCrop.width(); w >= dfDim.width(); w--) {
955*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
956*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
957*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
958*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
959*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
960*38e8c45fSAndroid Build Coastguard Worker             return w;
961*38e8c45fSAndroid Build Coastguard Worker         }
962*38e8c45fSAndroid Build Coastguard Worker     }
963*38e8c45fSAndroid Build Coastguard Worker     testPrintE("Failed to locate source crop max width");
964*38e8c45fSAndroid Build Coastguard Worker     exit(35);
965*38e8c45fSAndroid Build Coastguard Worker }
966*38e8c45fSAndroid Build Coastguard Worker 
967*38e8c45fSAndroid Build Coastguard Worker // Source crop maximum height
scMaxHeight(uint32_t format,const HwcTestDim & dfDim)968*38e8c45fSAndroid Build Coastguard Worker uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim)
969*38e8c45fSAndroid Build Coastguard Worker {
970*38e8c45fSAndroid Build Coastguard Worker     uint32_t h;
971*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
972*38e8c45fSAndroid Build Coastguard Worker 
973*38e8c45fSAndroid Build Coastguard Worker     for (h = searchLimits.sourceCrop.height(); h >= dfDim.height(); h--) {
974*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
975*38e8c45fSAndroid Build Coastguard Worker         rectList.clear();
976*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
977*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
978*38e8c45fSAndroid Build Coastguard Worker         if (num > 0) {
979*38e8c45fSAndroid Build Coastguard Worker             return h;
980*38e8c45fSAndroid Build Coastguard Worker         }
981*38e8c45fSAndroid Build Coastguard Worker     }
982*38e8c45fSAndroid Build Coastguard Worker     testPrintE("Failed to locate source crop max height");
983*38e8c45fSAndroid Build Coastguard Worker     exit(36);
984*38e8c45fSAndroid Build Coastguard Worker }
985*38e8c45fSAndroid Build Coastguard Worker 
986*38e8c45fSAndroid Build Coastguard Worker // Source crop minimum dimension
987*38e8c45fSAndroid Build Coastguard Worker // Discovers the source crop with the least number of pixels that the
988*38e8c45fSAndroid Build Coastguard Worker // HWC will commit to.  Note, this may be different from scMinWidth
989*38e8c45fSAndroid Build Coastguard Worker // * scMinHeight, in that this function searches for a combination of
990*38e8c45fSAndroid Build Coastguard Worker // width and height.  While the other routines always keep one of the
991*38e8c45fSAndroid Build Coastguard Worker // dimensions equal to the corresponding start dimension.
scMinDim(uint32_t format,const HwcTestDim & dfDim)992*38e8c45fSAndroid Build Coastguard Worker HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim)
993*38e8c45fSAndroid Build Coastguard Worker {
994*38e8c45fSAndroid Build Coastguard Worker     uint64_t bestMinPixels = 0;
995*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim bestDim;
996*38e8c45fSAndroid Build Coastguard Worker     bool bestSet = false; // True when value has been assigned to
997*38e8c45fSAndroid Build Coastguard Worker                           // bestMinPixels and bestDim
998*38e8c45fSAndroid Build Coastguard Worker 
999*38e8c45fSAndroid Build Coastguard Worker     bool origVerbose = verbose;  // Temporarily turn off verbose
1000*38e8c45fSAndroid Build Coastguard Worker     verbose = false;
1001*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t w = 1; w <= dfDim.width(); w++) {
1002*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t h = 1; h <= dfDim.height(); h++) {
1003*38e8c45fSAndroid Build Coastguard Worker             if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
1004*38e8c45fSAndroid Build Coastguard Worker                 break;
1005*38e8c45fSAndroid Build Coastguard Worker             }
1006*38e8c45fSAndroid Build Coastguard Worker 
1007*38e8c45fSAndroid Build Coastguard Worker             HwcTestDim dim(w, h);
1008*38e8c45fSAndroid Build Coastguard Worker             Rectangle rect(format, dfDim, HwcTestDim(w, h));
1009*38e8c45fSAndroid Build Coastguard Worker             list<Rectangle> rectList;
1010*38e8c45fSAndroid Build Coastguard Worker             rectList.push_back(rect);
1011*38e8c45fSAndroid Build Coastguard Worker             uint32_t num = numOverlays(rectList);
1012*38e8c45fSAndroid Build Coastguard Worker             if (num > 0) {
1013*38e8c45fSAndroid Build Coastguard Worker                 uint64_t pixels = dim.width() * dim.height();
1014*38e8c45fSAndroid Build Coastguard Worker                 if (!bestSet || (pixels < bestMinPixels)) {
1015*38e8c45fSAndroid Build Coastguard Worker                     bestMinPixels = pixels;
1016*38e8c45fSAndroid Build Coastguard Worker                     bestDim = dim;
1017*38e8c45fSAndroid Build Coastguard Worker                     bestSet = true;
1018*38e8c45fSAndroid Build Coastguard Worker                 }
1019*38e8c45fSAndroid Build Coastguard Worker             }
1020*38e8c45fSAndroid Build Coastguard Worker         }
1021*38e8c45fSAndroid Build Coastguard Worker     }
1022*38e8c45fSAndroid Build Coastguard Worker     verbose = origVerbose;
1023*38e8c45fSAndroid Build Coastguard Worker 
1024*38e8c45fSAndroid Build Coastguard Worker     if (!bestSet) {
1025*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unable to locate source crop min dimension");
1026*38e8c45fSAndroid Build Coastguard Worker         exit(20);
1027*38e8c45fSAndroid Build Coastguard Worker     }
1028*38e8c45fSAndroid Build Coastguard Worker 
1029*38e8c45fSAndroid Build Coastguard Worker     return bestDim;
1030*38e8c45fSAndroid Build Coastguard Worker }
1031*38e8c45fSAndroid Build Coastguard Worker 
1032*38e8c45fSAndroid Build Coastguard Worker // Source crop maximum dimension
scMaxDim(uint32_t format,const HwcTestDim & dfDim)1033*38e8c45fSAndroid Build Coastguard Worker HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim)
1034*38e8c45fSAndroid Build Coastguard Worker {
1035*38e8c45fSAndroid Build Coastguard Worker     uint64_t bestMaxPixels = 0;
1036*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim bestDim;
1037*38e8c45fSAndroid Build Coastguard Worker     bool bestSet = false; // True when value has been assigned to
1038*38e8c45fSAndroid Build Coastguard Worker                           // bestMaxPixels and bestDim;
1039*38e8c45fSAndroid Build Coastguard Worker 
1040*38e8c45fSAndroid Build Coastguard Worker     // Potentially increase benchmark performance by first checking
1041*38e8c45fSAndroid Build Coastguard Worker     // for the common case of supporting the maximum checked source size
1042*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim dim = searchLimits.sourceCrop;
1043*38e8c45fSAndroid Build Coastguard Worker     Rectangle rect(format, dfDim, searchLimits.sourceCrop);
1044*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
1045*38e8c45fSAndroid Build Coastguard Worker     rectList.push_back(rect);
1046*38e8c45fSAndroid Build Coastguard Worker     uint32_t num = numOverlays(rectList);
1047*38e8c45fSAndroid Build Coastguard Worker     if (num == 1) { return dim; }
1048*38e8c45fSAndroid Build Coastguard Worker 
1049*38e8c45fSAndroid Build Coastguard Worker     // TODO: Use a binary search
1050*38e8c45fSAndroid Build Coastguard Worker     bool origVerbose = verbose;  // Temporarily turn off verbose
1051*38e8c45fSAndroid Build Coastguard Worker     verbose = false;
1052*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t w = dfDim.width();
1053*38e8c45fSAndroid Build Coastguard Worker          w <= searchLimits.sourceCrop.width(); w++) {
1054*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t h = dfDim.height();
1055*38e8c45fSAndroid Build Coastguard Worker              h <= searchLimits.sourceCrop.height(); h++) {
1056*38e8c45fSAndroid Build Coastguard Worker             if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }
1057*38e8c45fSAndroid Build Coastguard Worker 
1058*38e8c45fSAndroid Build Coastguard Worker             HwcTestDim dim(w, h);
1059*38e8c45fSAndroid Build Coastguard Worker             Rectangle rect(format, dfDim, dim);
1060*38e8c45fSAndroid Build Coastguard Worker             list<Rectangle> rectList;
1061*38e8c45fSAndroid Build Coastguard Worker             rectList.push_back(rect);
1062*38e8c45fSAndroid Build Coastguard Worker             uint32_t num = numOverlays(rectList);
1063*38e8c45fSAndroid Build Coastguard Worker             if (num > 0) {
1064*38e8c45fSAndroid Build Coastguard Worker                 uint64_t pixels = dim.width() * dim.height();
1065*38e8c45fSAndroid Build Coastguard Worker                 if (!bestSet || (pixels > bestMaxPixels)) {
1066*38e8c45fSAndroid Build Coastguard Worker                     bestMaxPixels = pixels;
1067*38e8c45fSAndroid Build Coastguard Worker                     bestDim = dim;
1068*38e8c45fSAndroid Build Coastguard Worker                     bestSet = true;
1069*38e8c45fSAndroid Build Coastguard Worker                 }
1070*38e8c45fSAndroid Build Coastguard Worker             }
1071*38e8c45fSAndroid Build Coastguard Worker         }
1072*38e8c45fSAndroid Build Coastguard Worker     }
1073*38e8c45fSAndroid Build Coastguard Worker     verbose = origVerbose;
1074*38e8c45fSAndroid Build Coastguard Worker 
1075*38e8c45fSAndroid Build Coastguard Worker     if (!bestSet) {
1076*38e8c45fSAndroid Build Coastguard Worker         testPrintE("Unable to locate source crop max dimension");
1077*38e8c45fSAndroid Build Coastguard Worker         exit(21);
1078*38e8c45fSAndroid Build Coastguard Worker     }
1079*38e8c45fSAndroid Build Coastguard Worker 
1080*38e8c45fSAndroid Build Coastguard Worker     return bestDim;
1081*38e8c45fSAndroid Build Coastguard Worker }
1082*38e8c45fSAndroid Build Coastguard Worker 
1083*38e8c45fSAndroid Build Coastguard Worker // Source crop horizontal scale
1084*38e8c45fSAndroid Build Coastguard Worker // Determines the maximum factor by which the source crop can be larger
1085*38e8c45fSAndroid Build Coastguard Worker // that the display frame.  The commit point is discovered through a
1086*38e8c45fSAndroid Build Coastguard Worker // binary search of rational numbers.  The numerator in each of the
1087*38e8c45fSAndroid Build Coastguard Worker // rational numbers contains the dimension for the source crop, while
1088*38e8c45fSAndroid Build Coastguard Worker // the denominator specifies the dimension for the display frame.  On
1089*38e8c45fSAndroid Build Coastguard Worker // each pass of the binary search the mid-point between the greatest
1090*38e8c45fSAndroid Build Coastguard Worker // point committed to (best) and the smallest point in which a commit
1091*38e8c45fSAndroid Build Coastguard Worker // has failed is calculated.  This mid-point is then passed to a function
1092*38e8c45fSAndroid Build Coastguard Worker // named double2Rational, which determines the closest rational numbers
1093*38e8c45fSAndroid Build Coastguard Worker // just below and above the mid-point.  By default the lower rational
1094*38e8c45fSAndroid Build Coastguard Worker // number is used for the scale factor on the next pass of the binary
1095*38e8c45fSAndroid Build Coastguard Worker // search.  The upper value is only used when best is already equal
1096*38e8c45fSAndroid Build Coastguard Worker // to the lower value.  This only occurs when the lower value has already
1097*38e8c45fSAndroid Build Coastguard Worker // been tried.
scHScale(uint32_t format,const HwcTestDim & dfMin,const HwcTestDim & dfMax,const HwcTestDim & scMin,const HwcTestDim & scMax,HwcTestDim & outBestDf,HwcTestDim & outBestSc)1098*38e8c45fSAndroid Build Coastguard Worker Rational scHScale(uint32_t format,
1099*38e8c45fSAndroid Build Coastguard Worker                       const HwcTestDim& dfMin, const HwcTestDim& dfMax,
1100*38e8c45fSAndroid Build Coastguard Worker                       const HwcTestDim& scMin, const HwcTestDim& scMax,
1101*38e8c45fSAndroid Build Coastguard Worker                       HwcTestDim& outBestDf, HwcTestDim& outBestSc)
1102*38e8c45fSAndroid Build Coastguard Worker {
1103*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim scDim, dfDim; // Source crop and display frame dimension
1104*38e8c45fSAndroid Build Coastguard Worker     Rational best(0, 1), minBad;  // Current bounds for a binary search
1105*38e8c45fSAndroid Build Coastguard Worker                                   // MinGood is set below the lowest
1106*38e8c45fSAndroid Build Coastguard Worker                                   // possible scale.  The value of minBad,
1107*38e8c45fSAndroid Build Coastguard Worker                                   // will be set by the first pass
1108*38e8c45fSAndroid Build Coastguard Worker                                   // of the binary search.
1109*38e8c45fSAndroid Build Coastguard Worker 
1110*38e8c45fSAndroid Build Coastguard Worker     // Perform the passes of the binary search
1111*38e8c45fSAndroid Build Coastguard Worker     bool firstPass = true;
1112*38e8c45fSAndroid Build Coastguard Worker     do {
1113*38e8c45fSAndroid Build Coastguard Worker         // On first pass try the maximum scale within the search limits
1114*38e8c45fSAndroid Build Coastguard Worker         if (firstPass) {
1115*38e8c45fSAndroid Build Coastguard Worker             // Try the maximum possible scale, within the search limits
1116*38e8c45fSAndroid Build Coastguard Worker             scDim = HwcTestDim(searchLimits.sourceCrop.width(), scMin.height());
1117*38e8c45fSAndroid Build Coastguard Worker             dfDim = dfMin;
1118*38e8c45fSAndroid Build Coastguard Worker         } else {
1119*38e8c45fSAndroid Build Coastguard Worker             // Subsequent pass
1120*38e8c45fSAndroid Build Coastguard Worker             // Halve the difference between best and minBad.
1121*38e8c45fSAndroid Build Coastguard Worker             Rational lower, upper, selected;
1122*38e8c45fSAndroid Build Coastguard Worker 
1123*38e8c45fSAndroid Build Coastguard Worker             // Try the closest ratio halfway between minBood and minBad;
1124*38e8c45fSAndroid Build Coastguard Worker             // TODO: Avoid rounding issue by using Rational type for
1125*38e8c45fSAndroid Build Coastguard Worker             //       midpoint.  For now will use double, which should
1126*38e8c45fSAndroid Build Coastguard Worker             //       have more than sufficient resolution.
1127*38e8c45fSAndroid Build Coastguard Worker             double mid = (double) best
1128*38e8c45fSAndroid Build Coastguard Worker                          + ((double) minBad - (double) best) / 2.0;
1129*38e8c45fSAndroid Build Coastguard Worker             Rational::double2Rational(mid,
1130*38e8c45fSAndroid Build Coastguard Worker                             Range(scMin.width(), scMax.width()),
1131*38e8c45fSAndroid Build Coastguard Worker                             Range(dfMin.width(), dfMax.width()),
1132*38e8c45fSAndroid Build Coastguard Worker                             lower, upper);
1133*38e8c45fSAndroid Build Coastguard Worker             if (((lower == best) && (upper == minBad))) {
1134*38e8c45fSAndroid Build Coastguard Worker                 return best;
1135*38e8c45fSAndroid Build Coastguard Worker             }
1136*38e8c45fSAndroid Build Coastguard Worker 
1137*38e8c45fSAndroid Build Coastguard Worker             // Use lower value unless its already been tried
1138*38e8c45fSAndroid Build Coastguard Worker             selected = (lower != best) ? lower : upper;
1139*38e8c45fSAndroid Build Coastguard Worker 
1140*38e8c45fSAndroid Build Coastguard Worker             // Assign the size of the source crop and display frame
1141*38e8c45fSAndroid Build Coastguard Worker             // from the selected ratio of source crop to display frame.
1142*38e8c45fSAndroid Build Coastguard Worker             scDim = HwcTestDim(selected.numerator(), scMin.height());
1143*38e8c45fSAndroid Build Coastguard Worker             dfDim = HwcTestDim(selected.denominator(), dfMin.height());
1144*38e8c45fSAndroid Build Coastguard Worker         }
1145*38e8c45fSAndroid Build Coastguard Worker 
1146*38e8c45fSAndroid Build Coastguard Worker         // See if the HWC will commit to this combination
1147*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, scDim);
1148*38e8c45fSAndroid Build Coastguard Worker         list<Rectangle> rectList;
1149*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
1150*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
1151*38e8c45fSAndroid Build Coastguard Worker 
1152*38e8c45fSAndroid Build Coastguard Worker         if (verbose) {
1153*38e8c45fSAndroid Build Coastguard Worker             testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
1154*38e8c45fSAndroid Build Coastguard Worker                        num, (float) Rational(scDim.width(), dfDim.width()),
1155*38e8c45fSAndroid Build Coastguard Worker                        ((string) dfDim).c_str(), ((string) scDim).c_str());
1156*38e8c45fSAndroid Build Coastguard Worker         }
1157*38e8c45fSAndroid Build Coastguard Worker         if (num == 1) {
1158*38e8c45fSAndroid Build Coastguard Worker             // HWC committed to the combination
1159*38e8c45fSAndroid Build Coastguard Worker             // This is the best scale factor seen so far.  Report the
1160*38e8c45fSAndroid Build Coastguard Worker             // dimensions to the caller, in case nothing better is seen.
1161*38e8c45fSAndroid Build Coastguard Worker             outBestDf = dfDim;
1162*38e8c45fSAndroid Build Coastguard Worker             outBestSc = scDim;
1163*38e8c45fSAndroid Build Coastguard Worker 
1164*38e8c45fSAndroid Build Coastguard Worker             // Success on the first pass means the largest possible scale
1165*38e8c45fSAndroid Build Coastguard Worker             // is supported, in which case no need to search any further.
1166*38e8c45fSAndroid Build Coastguard Worker             if (firstPass) { return Rational(scDim.width(), dfDim.width()); }
1167*38e8c45fSAndroid Build Coastguard Worker 
1168*38e8c45fSAndroid Build Coastguard Worker             // Update the lower bound of the binary search
1169*38e8c45fSAndroid Build Coastguard Worker             best = Rational(scDim.width(), dfDim.width());
1170*38e8c45fSAndroid Build Coastguard Worker         } else {
1171*38e8c45fSAndroid Build Coastguard Worker             // HWC didn't commit to this combination, so update the
1172*38e8c45fSAndroid Build Coastguard Worker             // upper bound of the binary search.
1173*38e8c45fSAndroid Build Coastguard Worker             minBad = Rational(scDim.width(), dfDim.width());
1174*38e8c45fSAndroid Build Coastguard Worker         }
1175*38e8c45fSAndroid Build Coastguard Worker 
1176*38e8c45fSAndroid Build Coastguard Worker         firstPass = false;
1177*38e8c45fSAndroid Build Coastguard Worker     } while (best != minBad);
1178*38e8c45fSAndroid Build Coastguard Worker 
1179*38e8c45fSAndroid Build Coastguard Worker     return best;
1180*38e8c45fSAndroid Build Coastguard Worker }
1181*38e8c45fSAndroid Build Coastguard Worker 
1182*38e8c45fSAndroid Build Coastguard Worker // Source crop vertical scale
1183*38e8c45fSAndroid Build Coastguard Worker // Determines the maximum factor by which the source crop can be larger
1184*38e8c45fSAndroid Build Coastguard Worker // that the display frame.  The commit point is discovered through a
1185*38e8c45fSAndroid Build Coastguard Worker // binary search of rational numbers.  The numerator in each of the
1186*38e8c45fSAndroid Build Coastguard Worker // rational numbers contains the dimension for the source crop, while
1187*38e8c45fSAndroid Build Coastguard Worker // the denominator specifies the dimension for the display frame.  On
1188*38e8c45fSAndroid Build Coastguard Worker // each pass of the binary search the mid-point between the greatest
1189*38e8c45fSAndroid Build Coastguard Worker // point committed to (best) and the smallest point in which a commit
1190*38e8c45fSAndroid Build Coastguard Worker // has failed is calculated.  This mid-point is then passed to a function
1191*38e8c45fSAndroid Build Coastguard Worker // named double2Rational, which determines the closest rational numbers
1192*38e8c45fSAndroid Build Coastguard Worker // just below and above the mid-point.  By default the lower rational
1193*38e8c45fSAndroid Build Coastguard Worker // number is used for the scale factor on the next pass of the binary
1194*38e8c45fSAndroid Build Coastguard Worker // search.  The upper value is only used when best is already equal
1195*38e8c45fSAndroid Build Coastguard Worker // to the lower value.  This only occurs when the lower value has already
1196*38e8c45fSAndroid Build Coastguard Worker // been tried.
scVScale(uint32_t format,const HwcTestDim & dfMin,const HwcTestDim & dfMax,const HwcTestDim & scMin,const HwcTestDim & scMax,HwcTestDim & outBestDf,HwcTestDim & outBestSc)1197*38e8c45fSAndroid Build Coastguard Worker Rational scVScale(uint32_t format,
1198*38e8c45fSAndroid Build Coastguard Worker                       const HwcTestDim& dfMin, const HwcTestDim& dfMax,
1199*38e8c45fSAndroid Build Coastguard Worker                       const HwcTestDim& scMin, const HwcTestDim& scMax,
1200*38e8c45fSAndroid Build Coastguard Worker                       HwcTestDim& outBestDf, HwcTestDim& outBestSc)
1201*38e8c45fSAndroid Build Coastguard Worker {
1202*38e8c45fSAndroid Build Coastguard Worker     HwcTestDim scDim, dfDim; // Source crop and display frame dimension
1203*38e8c45fSAndroid Build Coastguard Worker     Rational best(0, 1), minBad;  // Current bounds for a binary search
1204*38e8c45fSAndroid Build Coastguard Worker                                   // MinGood is set below the lowest
1205*38e8c45fSAndroid Build Coastguard Worker                                   // possible scale.  The value of minBad,
1206*38e8c45fSAndroid Build Coastguard Worker                                   // will be set by the first pass
1207*38e8c45fSAndroid Build Coastguard Worker                                   // of the binary search.
1208*38e8c45fSAndroid Build Coastguard Worker 
1209*38e8c45fSAndroid Build Coastguard Worker     // Perform the passes of the binary search
1210*38e8c45fSAndroid Build Coastguard Worker     bool firstPass = true;
1211*38e8c45fSAndroid Build Coastguard Worker     do {
1212*38e8c45fSAndroid Build Coastguard Worker         // On first pass try the maximum scale within the search limits
1213*38e8c45fSAndroid Build Coastguard Worker         if (firstPass) {
1214*38e8c45fSAndroid Build Coastguard Worker             // Try the maximum possible scale, within the search limits
1215*38e8c45fSAndroid Build Coastguard Worker             scDim = HwcTestDim(scMin.width(), searchLimits.sourceCrop.height());
1216*38e8c45fSAndroid Build Coastguard Worker             dfDim = dfMin;
1217*38e8c45fSAndroid Build Coastguard Worker         } else {
1218*38e8c45fSAndroid Build Coastguard Worker             // Subsequent pass
1219*38e8c45fSAndroid Build Coastguard Worker             // Halve the difference between best and minBad.
1220*38e8c45fSAndroid Build Coastguard Worker             Rational lower, upper, selected;
1221*38e8c45fSAndroid Build Coastguard Worker 
1222*38e8c45fSAndroid Build Coastguard Worker             // Try the closest ratio halfway between minBood and minBad;
1223*38e8c45fSAndroid Build Coastguard Worker             // TODO: Avoid rounding issue by using Rational type for
1224*38e8c45fSAndroid Build Coastguard Worker             //       midpoint.  For now will use double, which should
1225*38e8c45fSAndroid Build Coastguard Worker             //       have more than sufficient resolution.
1226*38e8c45fSAndroid Build Coastguard Worker             double mid = (double) best
1227*38e8c45fSAndroid Build Coastguard Worker                          + ((double) minBad - (double) best) / 2.0;
1228*38e8c45fSAndroid Build Coastguard Worker             Rational::double2Rational(mid,
1229*38e8c45fSAndroid Build Coastguard Worker                             Range(scMin.height(), scMax.height()),
1230*38e8c45fSAndroid Build Coastguard Worker                             Range(dfMin.height(), dfMax.height()),
1231*38e8c45fSAndroid Build Coastguard Worker                             lower, upper);
1232*38e8c45fSAndroid Build Coastguard Worker             if (((lower == best) && (upper == minBad))) {
1233*38e8c45fSAndroid Build Coastguard Worker                 return best;
1234*38e8c45fSAndroid Build Coastguard Worker             }
1235*38e8c45fSAndroid Build Coastguard Worker 
1236*38e8c45fSAndroid Build Coastguard Worker             // Use lower value unless its already been tried
1237*38e8c45fSAndroid Build Coastguard Worker             selected = (lower != best) ? lower : upper;
1238*38e8c45fSAndroid Build Coastguard Worker 
1239*38e8c45fSAndroid Build Coastguard Worker             // Assign the size of the source crop and display frame
1240*38e8c45fSAndroid Build Coastguard Worker             // from the selected ratio of source crop to display frame.
1241*38e8c45fSAndroid Build Coastguard Worker             scDim = HwcTestDim(scMin.width(), selected.numerator());
1242*38e8c45fSAndroid Build Coastguard Worker             dfDim = HwcTestDim(dfMin.width(), selected.denominator());
1243*38e8c45fSAndroid Build Coastguard Worker         }
1244*38e8c45fSAndroid Build Coastguard Worker 
1245*38e8c45fSAndroid Build Coastguard Worker         // See if the HWC will commit to this combination
1246*38e8c45fSAndroid Build Coastguard Worker         Rectangle rect(format, dfDim, scDim);
1247*38e8c45fSAndroid Build Coastguard Worker         list<Rectangle> rectList;
1248*38e8c45fSAndroid Build Coastguard Worker         rectList.push_back(rect);
1249*38e8c45fSAndroid Build Coastguard Worker         uint32_t num = numOverlays(rectList);
1250*38e8c45fSAndroid Build Coastguard Worker 
1251*38e8c45fSAndroid Build Coastguard Worker         if (verbose) {
1252*38e8c45fSAndroid Build Coastguard Worker             testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
1253*38e8c45fSAndroid Build Coastguard Worker                        num, (float) Rational(scDim.height(), dfDim.height()),
1254*38e8c45fSAndroid Build Coastguard Worker                        ((string) dfDim).c_str(), ((string) scDim).c_str());
1255*38e8c45fSAndroid Build Coastguard Worker         }
1256*38e8c45fSAndroid Build Coastguard Worker         if (num == 1) {
1257*38e8c45fSAndroid Build Coastguard Worker             // HWC committed to the combination
1258*38e8c45fSAndroid Build Coastguard Worker             // This is the best scale factor seen so far.  Report the
1259*38e8c45fSAndroid Build Coastguard Worker             // dimensions to the caller, in case nothing better is seen.
1260*38e8c45fSAndroid Build Coastguard Worker             outBestDf = dfDim;
1261*38e8c45fSAndroid Build Coastguard Worker             outBestSc = scDim;
1262*38e8c45fSAndroid Build Coastguard Worker 
1263*38e8c45fSAndroid Build Coastguard Worker             // Success on the first pass means the largest possible scale
1264*38e8c45fSAndroid Build Coastguard Worker             // is supported, in which case no need to search any further.
1265*38e8c45fSAndroid Build Coastguard Worker             if (firstPass) { return Rational(scDim.height(), dfDim.height()); }
1266*38e8c45fSAndroid Build Coastguard Worker 
1267*38e8c45fSAndroid Build Coastguard Worker             // Update the lower bound of the binary search
1268*38e8c45fSAndroid Build Coastguard Worker             best = Rational(scDim.height(), dfDim.height());
1269*38e8c45fSAndroid Build Coastguard Worker         } else {
1270*38e8c45fSAndroid Build Coastguard Worker             // HWC didn't commit to this combination, so update the
1271*38e8c45fSAndroid Build Coastguard Worker             // upper bound of the binary search.
1272*38e8c45fSAndroid Build Coastguard Worker             minBad = Rational(scDim.height(), dfDim.height());
1273*38e8c45fSAndroid Build Coastguard Worker         }
1274*38e8c45fSAndroid Build Coastguard Worker 
1275*38e8c45fSAndroid Build Coastguard Worker         firstPass = false;
1276*38e8c45fSAndroid Build Coastguard Worker     } while (best != minBad);
1277*38e8c45fSAndroid Build Coastguard Worker 
1278*38e8c45fSAndroid Build Coastguard Worker     return best;
1279*38e8c45fSAndroid Build Coastguard Worker }
1280*38e8c45fSAndroid Build Coastguard Worker 
numOverlapping(uint32_t backgroundFormat,uint32_t foregroundFormat,uint32_t backgroundBlend,uint32_t foregroundBlend)1281*38e8c45fSAndroid Build Coastguard Worker uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
1282*38e8c45fSAndroid Build Coastguard Worker                         uint32_t backgroundBlend, uint32_t foregroundBlend)
1283*38e8c45fSAndroid Build Coastguard Worker {
1284*38e8c45fSAndroid Build Coastguard Worker     list<Rectangle> rectList;
1285*38e8c45fSAndroid Build Coastguard Worker 
1286*38e8c45fSAndroid Build Coastguard Worker     Rectangle background(backgroundFormat, startDim, startDim);
1287*38e8c45fSAndroid Build Coastguard Worker     background.blend = backgroundBlend;
1288*38e8c45fSAndroid Build Coastguard Worker     rectList.push_back(background);
1289*38e8c45fSAndroid Build Coastguard Worker 
1290*38e8c45fSAndroid Build Coastguard Worker     // TODO: Handle cases where startDim is so small that adding 5
1291*38e8c45fSAndroid Build Coastguard Worker     //       causes frames not to overlap.
1292*38e8c45fSAndroid Build Coastguard Worker     // TODO: Handle cases where startDim is so large that adding 5
1293*38e8c45fSAndroid Build Coastguard Worker     //       cause a portion or all of the foreground displayFrame
1294*38e8c45fSAndroid Build Coastguard Worker     //       to be off the display.
1295*38e8c45fSAndroid Build Coastguard Worker     Rectangle foreground(foregroundFormat, startDim, startDim);
1296*38e8c45fSAndroid Build Coastguard Worker     foreground.displayFrame.left += 5;
1297*38e8c45fSAndroid Build Coastguard Worker     foreground.displayFrame.top += 5;
1298*38e8c45fSAndroid Build Coastguard Worker     foreground.displayFrame.right += 5;
1299*38e8c45fSAndroid Build Coastguard Worker     foreground.displayFrame.bottom += 5;
1300*38e8c45fSAndroid Build Coastguard Worker     background.blend = foregroundBlend;
1301*38e8c45fSAndroid Build Coastguard Worker     rectList.push_back(foreground);
1302*38e8c45fSAndroid Build Coastguard Worker 
1303*38e8c45fSAndroid Build Coastguard Worker     uint32_t num = numOverlays(rectList);
1304*38e8c45fSAndroid Build Coastguard Worker 
1305*38e8c45fSAndroid Build Coastguard Worker     return num;
1306*38e8c45fSAndroid Build Coastguard Worker }
1307*38e8c45fSAndroid Build Coastguard Worker 
Rectangle(uint32_t graphicFormat,HwcTestDim dfDim,HwcTestDim sDim)1308*38e8c45fSAndroid Build Coastguard Worker Rectangle::Rectangle(uint32_t graphicFormat, HwcTestDim dfDim,
1309*38e8c45fSAndroid Build Coastguard Worker                      HwcTestDim sDim) :
1310*38e8c45fSAndroid Build Coastguard Worker     format(graphicFormat), transform(defaultTransform),
1311*38e8c45fSAndroid Build Coastguard Worker     blend(defaultBlend), color(defaultColor), alpha(defaultAlpha),
1312*38e8c45fSAndroid Build Coastguard Worker     sourceCrop(sDim), displayFrame(dfDim)
1313*38e8c45fSAndroid Build Coastguard Worker {
1314*38e8c45fSAndroid Build Coastguard Worker     // Set source dimension
1315*38e8c45fSAndroid Build Coastguard Worker     // Can't use a base initializer, because the setting of format
1316*38e8c45fSAndroid Build Coastguard Worker     // must be done before setting the sourceDimension.
1317*38e8c45fSAndroid Build Coastguard Worker     setSourceDim(sDim);
1318*38e8c45fSAndroid Build Coastguard Worker }
1319*38e8c45fSAndroid Build Coastguard Worker 
setSourceDim(HwcTestDim dim)1320*38e8c45fSAndroid Build Coastguard Worker void Rectangle::setSourceDim(HwcTestDim dim)
1321*38e8c45fSAndroid Build Coastguard Worker {
1322*38e8c45fSAndroid Build Coastguard Worker     this->sourceDim = dim;
1323*38e8c45fSAndroid Build Coastguard Worker 
1324*38e8c45fSAndroid Build Coastguard Worker     const struct hwcTestGraphicFormat *attrib;
1325*38e8c45fSAndroid Build Coastguard Worker     attrib = hwcTestGraphicFormatLookup(this->format);
1326*38e8c45fSAndroid Build Coastguard Worker     if (attrib != NULL) {
1327*38e8c45fSAndroid Build Coastguard Worker         if (sourceDim.width() % attrib->wMod) {
1328*38e8c45fSAndroid Build Coastguard Worker             sourceDim.setWidth(sourceDim.width() + attrib->wMod
1329*38e8c45fSAndroid Build Coastguard Worker             - (sourceDim.width() % attrib->wMod));
1330*38e8c45fSAndroid Build Coastguard Worker         }
1331*38e8c45fSAndroid Build Coastguard Worker         if (sourceDim.height() % attrib->hMod) {
1332*38e8c45fSAndroid Build Coastguard Worker             sourceDim.setHeight(sourceDim.height() + attrib->hMod
1333*38e8c45fSAndroid Build Coastguard Worker             - (sourceDim.height() % attrib->hMod));
1334*38e8c45fSAndroid Build Coastguard Worker         }
1335*38e8c45fSAndroid Build Coastguard Worker     }
1336*38e8c45fSAndroid Build Coastguard Worker }
1337*38e8c45fSAndroid Build Coastguard Worker 
1338*38e8c45fSAndroid Build Coastguard Worker // Rational member functions
operator ==(const Rational & other) const1339*38e8c45fSAndroid Build Coastguard Worker bool Rational::operator==(const Rational& other) const
1340*38e8c45fSAndroid Build Coastguard Worker {
1341*38e8c45fSAndroid Build Coastguard Worker     if (((uint64_t) _n * other._d)
1342*38e8c45fSAndroid Build Coastguard Worker         == ((uint64_t) _d * other._n)) { return true; }
1343*38e8c45fSAndroid Build Coastguard Worker 
1344*38e8c45fSAndroid Build Coastguard Worker     return false;
1345*38e8c45fSAndroid Build Coastguard Worker }
1346*38e8c45fSAndroid Build Coastguard Worker 
operator <(const Rational & other) const1347*38e8c45fSAndroid Build Coastguard Worker bool Rational::operator<(const Rational& other) const
1348*38e8c45fSAndroid Build Coastguard Worker {
1349*38e8c45fSAndroid Build Coastguard Worker     if (((uint64_t) _n * other._d)
1350*38e8c45fSAndroid Build Coastguard Worker         < ((uint64_t) _d * other._n)) { return true; }
1351*38e8c45fSAndroid Build Coastguard Worker 
1352*38e8c45fSAndroid Build Coastguard Worker     return false;
1353*38e8c45fSAndroid Build Coastguard Worker }
1354*38e8c45fSAndroid Build Coastguard Worker 
operator string() const1355*38e8c45fSAndroid Build Coastguard Worker Rational::operator string() const
1356*38e8c45fSAndroid Build Coastguard Worker {
1357*38e8c45fSAndroid Build Coastguard Worker     ostringstream out;
1358*38e8c45fSAndroid Build Coastguard Worker 
1359*38e8c45fSAndroid Build Coastguard Worker     out << _n << '/' << _d;
1360*38e8c45fSAndroid Build Coastguard Worker 
1361*38e8c45fSAndroid Build Coastguard Worker     return out.str();
1362*38e8c45fSAndroid Build Coastguard Worker }
1363*38e8c45fSAndroid Build Coastguard Worker 
double2Rational(double f,Range nRange,Range dRange,Rational & lower,Rational & upper)1364*38e8c45fSAndroid Build Coastguard Worker void Rational::double2Rational(double f, Range nRange, Range dRange,
1365*38e8c45fSAndroid Build Coastguard Worker                     Rational& lower, Rational& upper)
1366*38e8c45fSAndroid Build Coastguard Worker {
1367*38e8c45fSAndroid Build Coastguard Worker     Rational bestLower(nRange.lower(), dRange.upper());
1368*38e8c45fSAndroid Build Coastguard Worker     Rational bestUpper(nRange.upper(), dRange.lower());
1369*38e8c45fSAndroid Build Coastguard Worker 
1370*38e8c45fSAndroid Build Coastguard Worker     // Search for a better solution
1371*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t d = dRange.lower(); d <= dRange.upper(); d++) {
1372*38e8c45fSAndroid Build Coastguard Worker         Rational val(d * f, d);  // Lower, because double to int cast truncates
1373*38e8c45fSAndroid Build Coastguard Worker 
1374*38e8c45fSAndroid Build Coastguard Worker         if ((val.numerator() < nRange.lower())
1375*38e8c45fSAndroid Build Coastguard Worker             || (val.numerator() > nRange.upper())) { continue; }
1376*38e8c45fSAndroid Build Coastguard Worker 
1377*38e8c45fSAndroid Build Coastguard Worker         if (((double) val > (double) bestLower) && ((double) val <= f)) {
1378*38e8c45fSAndroid Build Coastguard Worker             bestLower = val;
1379*38e8c45fSAndroid Build Coastguard Worker         }
1380*38e8c45fSAndroid Build Coastguard Worker 
1381*38e8c45fSAndroid Build Coastguard Worker         val.setNumerator(val.numerator() + 1);
1382*38e8c45fSAndroid Build Coastguard Worker         if (val.numerator() > nRange.upper()) { continue; }
1383*38e8c45fSAndroid Build Coastguard Worker 
1384*38e8c45fSAndroid Build Coastguard Worker         if (((double) val < (double) bestUpper) && ((double) val >= f)) {
1385*38e8c45fSAndroid Build Coastguard Worker             bestUpper = val;
1386*38e8c45fSAndroid Build Coastguard Worker         }
1387*38e8c45fSAndroid Build Coastguard Worker     }
1388*38e8c45fSAndroid Build Coastguard Worker 
1389*38e8c45fSAndroid Build Coastguard Worker     lower = bestLower;
1390*38e8c45fSAndroid Build Coastguard Worker     upper = bestUpper;
1391*38e8c45fSAndroid Build Coastguard Worker }
1392*38e8c45fSAndroid Build Coastguard Worker 
1393*38e8c45fSAndroid Build Coastguard Worker // Local functions
1394*38e8c45fSAndroid Build Coastguard Worker 
1395*38e8c45fSAndroid Build Coastguard Worker // Num Overlays
1396*38e8c45fSAndroid Build Coastguard Worker // Given a list of rectangles, determine how many HWC will commit to render
numOverlays(list<Rectangle> & rectList)1397*38e8c45fSAndroid Build Coastguard Worker uint32_t numOverlays(list<Rectangle>& rectList)
1398*38e8c45fSAndroid Build Coastguard Worker {
1399*38e8c45fSAndroid Build Coastguard Worker     hwc_display_contents_1_t *hwcList;
1400*38e8c45fSAndroid Build Coastguard Worker     list<sp<GraphicBuffer> > buffers;
1401*38e8c45fSAndroid Build Coastguard Worker 
1402*38e8c45fSAndroid Build Coastguard Worker     hwcList = hwcTestCreateLayerList(rectList.size());
1403*38e8c45fSAndroid Build Coastguard Worker     if (hwcList == NULL) {
1404*38e8c45fSAndroid Build Coastguard Worker         testPrintE("numOverlays create hwcList failed");
1405*38e8c45fSAndroid Build Coastguard Worker         exit(30);
1406*38e8c45fSAndroid Build Coastguard Worker     }
1407*38e8c45fSAndroid Build Coastguard Worker 
1408*38e8c45fSAndroid Build Coastguard Worker     hwc_layer_1_t *layer = &hwcList->hwLayers[0];
1409*38e8c45fSAndroid Build Coastguard Worker     for (std::list<Rectangle>::iterator it = rectList.begin();
1410*38e8c45fSAndroid Build Coastguard Worker          it != rectList.end(); ++it, ++layer) {
1411*38e8c45fSAndroid Build Coastguard Worker         // Allocate the texture for the source frame
1412*38e8c45fSAndroid Build Coastguard Worker         // and push it onto the buffers list, so that it
1413*38e8c45fSAndroid Build Coastguard Worker         // stays in scope until a return from this function.
1414*38e8c45fSAndroid Build Coastguard Worker         sp<GraphicBuffer> texture;
1415*38e8c45fSAndroid Build Coastguard Worker         texture  = new GraphicBuffer(it->sourceDim.width(),
1416*38e8c45fSAndroid Build Coastguard Worker                                      it->sourceDim.height(),
1417*38e8c45fSAndroid Build Coastguard Worker                                      it->format, texUsage);
1418*38e8c45fSAndroid Build Coastguard Worker         buffers.push_back(texture);
1419*38e8c45fSAndroid Build Coastguard Worker 
1420*38e8c45fSAndroid Build Coastguard Worker         layer->handle = texture->handle;
1421*38e8c45fSAndroid Build Coastguard Worker         layer->blending = it->blend;
1422*38e8c45fSAndroid Build Coastguard Worker         layer->transform = it->transform;
1423*38e8c45fSAndroid Build Coastguard Worker         layer->sourceCrop = it->sourceCrop;
1424*38e8c45fSAndroid Build Coastguard Worker         layer->displayFrame = it->displayFrame;
1425*38e8c45fSAndroid Build Coastguard Worker 
1426*38e8c45fSAndroid Build Coastguard Worker         layer->visibleRegionScreen.numRects = 1;
1427*38e8c45fSAndroid Build Coastguard Worker         layer->visibleRegionScreen.rects = &layer->displayFrame;
1428*38e8c45fSAndroid Build Coastguard Worker     }
1429*38e8c45fSAndroid Build Coastguard Worker 
1430*38e8c45fSAndroid Build Coastguard Worker     // Perform prepare operation
1431*38e8c45fSAndroid Build Coastguard Worker     if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(hwcList); }
1432*38e8c45fSAndroid Build Coastguard Worker     hwcDevice->prepare(hwcDevice, 1, &hwcList);
1433*38e8c45fSAndroid Build Coastguard Worker     if (verbose) {
1434*38e8c45fSAndroid Build Coastguard Worker         testPrintI("Post Prepare:");
1435*38e8c45fSAndroid Build Coastguard Worker         hwcTestDisplayListPrepareModifiable(hwcList);
1436*38e8c45fSAndroid Build Coastguard Worker     }
1437*38e8c45fSAndroid Build Coastguard Worker 
1438*38e8c45fSAndroid Build Coastguard Worker     // Count the number of overlays
1439*38e8c45fSAndroid Build Coastguard Worker     uint32_t total = 0;
1440*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int n1 = 0; n1 < hwcList->numHwLayers; n1++) {
1441*38e8c45fSAndroid Build Coastguard Worker         if (hwcList->hwLayers[n1].compositionType == HWC_OVERLAY) {
1442*38e8c45fSAndroid Build Coastguard Worker             total++;
1443*38e8c45fSAndroid Build Coastguard Worker         }
1444*38e8c45fSAndroid Build Coastguard Worker     }
1445*38e8c45fSAndroid Build Coastguard Worker 
1446*38e8c45fSAndroid Build Coastguard Worker     // Free the layer list and graphic buffers
1447*38e8c45fSAndroid Build Coastguard Worker     hwcTestFreeLayerList(hwcList);
1448*38e8c45fSAndroid Build Coastguard Worker 
1449*38e8c45fSAndroid Build Coastguard Worker     return total;
1450*38e8c45fSAndroid Build Coastguard Worker }
1451*38e8c45fSAndroid Build Coastguard Worker 
transformList2str(const list<uint32_t> & transformList)1452*38e8c45fSAndroid Build Coastguard Worker string transformList2str(const list<uint32_t>& transformList)
1453*38e8c45fSAndroid Build Coastguard Worker {
1454*38e8c45fSAndroid Build Coastguard Worker     ostringstream out;
1455*38e8c45fSAndroid Build Coastguard Worker 
1456*38e8c45fSAndroid Build Coastguard Worker     for (list<uint32_t>::const_iterator it = transformList.begin();
1457*38e8c45fSAndroid Build Coastguard Worker          it != transformList.end(); ++it) {
1458*38e8c45fSAndroid Build Coastguard Worker         uint32_t id = *it;
1459*38e8c45fSAndroid Build Coastguard Worker 
1460*38e8c45fSAndroid Build Coastguard Worker         if (it != transformList.begin()) {
1461*38e8c45fSAndroid Build Coastguard Worker             out << ", ";
1462*38e8c45fSAndroid Build Coastguard Worker         }
1463*38e8c45fSAndroid Build Coastguard Worker         out << id;
1464*38e8c45fSAndroid Build Coastguard Worker 
1465*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
1466*38e8c45fSAndroid Build Coastguard Worker             if (id == transformType[idx].id) {
1467*38e8c45fSAndroid Build Coastguard Worker                 out << " (" << transformType[idx].desc << ')';
1468*38e8c45fSAndroid Build Coastguard Worker                 break;
1469*38e8c45fSAndroid Build Coastguard Worker             }
1470*38e8c45fSAndroid Build Coastguard Worker         }
1471*38e8c45fSAndroid Build Coastguard Worker     }
1472*38e8c45fSAndroid Build Coastguard Worker 
1473*38e8c45fSAndroid Build Coastguard Worker     return out.str();
1474*38e8c45fSAndroid Build Coastguard Worker }
1475*38e8c45fSAndroid Build Coastguard Worker 
blendList2str(const list<uint32_t> & blendList)1476*38e8c45fSAndroid Build Coastguard Worker string blendList2str(const list<uint32_t>& blendList)
1477*38e8c45fSAndroid Build Coastguard Worker {
1478*38e8c45fSAndroid Build Coastguard Worker     ostringstream out;
1479*38e8c45fSAndroid Build Coastguard Worker 
1480*38e8c45fSAndroid Build Coastguard Worker     for (list<uint32_t>::const_iterator it = blendList.begin();
1481*38e8c45fSAndroid Build Coastguard Worker          it != blendList.end(); ++it) {
1482*38e8c45fSAndroid Build Coastguard Worker         uint32_t id = *it;
1483*38e8c45fSAndroid Build Coastguard Worker 
1484*38e8c45fSAndroid Build Coastguard Worker         if (it != blendList.begin()) {
1485*38e8c45fSAndroid Build Coastguard Worker             out << ", ";
1486*38e8c45fSAndroid Build Coastguard Worker         }
1487*38e8c45fSAndroid Build Coastguard Worker         out << id;
1488*38e8c45fSAndroid Build Coastguard Worker 
1489*38e8c45fSAndroid Build Coastguard Worker         for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
1490*38e8c45fSAndroid Build Coastguard Worker             if (id == blendType[idx].id) {
1491*38e8c45fSAndroid Build Coastguard Worker                 out << " (" << blendType[idx].desc << ')';
1492*38e8c45fSAndroid Build Coastguard Worker                 break;
1493*38e8c45fSAndroid Build Coastguard Worker             }
1494*38e8c45fSAndroid Build Coastguard Worker         }
1495*38e8c45fSAndroid Build Coastguard Worker     }
1496*38e8c45fSAndroid Build Coastguard Worker 
1497*38e8c45fSAndroid Build Coastguard Worker     return out.str();
1498*38e8c45fSAndroid Build Coastguard Worker }
1499*38e8c45fSAndroid Build Coastguard Worker 
init(void)1500*38e8c45fSAndroid Build Coastguard Worker void init(void)
1501*38e8c45fSAndroid Build Coastguard Worker {
1502*38e8c45fSAndroid Build Coastguard Worker     srand48(0);
1503*38e8c45fSAndroid Build Coastguard Worker 
1504*38e8c45fSAndroid Build Coastguard Worker     hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
1505*38e8c45fSAndroid Build Coastguard Worker 
1506*38e8c45fSAndroid Build Coastguard Worker     hwcTestOpenHwc(&hwcDevice);
1507*38e8c45fSAndroid Build Coastguard Worker }
1508*38e8c45fSAndroid Build Coastguard Worker 
printFormatHeadings(size_t indent)1509*38e8c45fSAndroid Build Coastguard Worker void printFormatHeadings(size_t indent)
1510*38e8c45fSAndroid Build Coastguard Worker {
1511*38e8c45fSAndroid Build Coastguard Worker     for (size_t row = 0; row <= maxHeadingLen; row++) {
1512*38e8c45fSAndroid Build Coastguard Worker         ostringstream line;
1513*38e8c45fSAndroid Build Coastguard Worker         for(vector<string>::iterator it = formats.begin();
1514*38e8c45fSAndroid Build Coastguard Worker             it != formats.end(); ++it) {
1515*38e8c45fSAndroid Build Coastguard Worker             if ((maxHeadingLen - row) <= it->length()) {
1516*38e8c45fSAndroid Build Coastguard Worker                 if (row != maxHeadingLen) {
1517*38e8c45fSAndroid Build Coastguard Worker                     char ch = (*it)[it->length() - (maxHeadingLen - row)];
1518*38e8c45fSAndroid Build Coastguard Worker                     line << ' ' << setw(printFieldWidth) << ch;
1519*38e8c45fSAndroid Build Coastguard Worker                 } else {
1520*38e8c45fSAndroid Build Coastguard Worker                     line << ' ' << string(printFieldWidth, '-');
1521*38e8c45fSAndroid Build Coastguard Worker                 }
1522*38e8c45fSAndroid Build Coastguard Worker             } else {
1523*38e8c45fSAndroid Build Coastguard Worker                line << ' ' << setw(printFieldWidth) << "";
1524*38e8c45fSAndroid Build Coastguard Worker             }
1525*38e8c45fSAndroid Build Coastguard Worker         }
1526*38e8c45fSAndroid Build Coastguard Worker         testPrintI("%*s%s", indent + maxHeadingLen, "",
1527*38e8c45fSAndroid Build Coastguard Worker                    line.str().c_str());
1528*38e8c45fSAndroid Build Coastguard Worker     }
1529*38e8c45fSAndroid Build Coastguard Worker }
1530*38e8c45fSAndroid Build Coastguard Worker 
printOverlapLine(size_t indent,const string formatStr,const vector<uint32_t> & results)1531*38e8c45fSAndroid Build Coastguard Worker void printOverlapLine(size_t indent, const string formatStr,
1532*38e8c45fSAndroid Build Coastguard Worker                         const vector<uint32_t>& results)
1533*38e8c45fSAndroid Build Coastguard Worker {
1534*38e8c45fSAndroid Build Coastguard Worker     ostringstream line;
1535*38e8c45fSAndroid Build Coastguard Worker 
1536*38e8c45fSAndroid Build Coastguard Worker     line << setw(indent + maxHeadingLen - formatStr.length()) << "";
1537*38e8c45fSAndroid Build Coastguard Worker 
1538*38e8c45fSAndroid Build Coastguard Worker     line << formatStr;
1539*38e8c45fSAndroid Build Coastguard Worker 
1540*38e8c45fSAndroid Build Coastguard Worker     for (vector<uint32_t>::const_iterator it = results.begin();
1541*38e8c45fSAndroid Build Coastguard Worker          it != results.end(); ++it) {
1542*38e8c45fSAndroid Build Coastguard Worker         line << ' ' << setw(printFieldWidth) << *it;
1543*38e8c45fSAndroid Build Coastguard Worker     }
1544*38e8c45fSAndroid Build Coastguard Worker 
1545*38e8c45fSAndroid Build Coastguard Worker     testPrintI("%s", line.str().c_str());
1546*38e8c45fSAndroid Build Coastguard Worker }
1547*38e8c45fSAndroid Build Coastguard Worker 
printSyntax(const char * cmd)1548*38e8c45fSAndroid Build Coastguard Worker void printSyntax(const char *cmd)
1549*38e8c45fSAndroid Build Coastguard Worker {
1550*38e8c45fSAndroid Build Coastguard Worker     testPrintE("  %s [options] [graphicFormat] ...",
1551*38e8c45fSAndroid Build Coastguard Worker                cmd);
1552*38e8c45fSAndroid Build Coastguard Worker     testPrintE("    options:");
1553*38e8c45fSAndroid Build Coastguard Worker     testPrintE("      -s [width, height] - start dimension");
1554*38e8c45fSAndroid Build Coastguard Worker     testPrintE("      -v - Verbose");
1555*38e8c45fSAndroid Build Coastguard Worker     testPrintE("");
1556*38e8c45fSAndroid Build Coastguard Worker     testPrintE("    graphic formats:");
1557*38e8c45fSAndroid Build Coastguard Worker     for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
1558*38e8c45fSAndroid Build Coastguard Worker         testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
1559*38e8c45fSAndroid Build Coastguard Worker     }
1560*38e8c45fSAndroid Build Coastguard Worker }
1561