1734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/*
2734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Copyright (C) 2011 The Android Open Source Project
3734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
4734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Licensed under the Apache License, Version 2.0 (the "License");
5734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * you may not use this file except in compliance with the License.
6734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * You may obtain a copy of the License at
7734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
8734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      http://www.apache.org/licenses/LICENSE-2.0
9734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
10734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Unless required by applicable law or agreed to in writing, software
11734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * distributed under the License is distributed on an "AS IS" BASIS,
12734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * See the License for the specific language governing permissions and
14734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * limitations under the License.
15734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */
16734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
17734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/*
18734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Hardware Composer Rectangles
19734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
20734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Synopsis
21734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   hwcRects [options] (graphicFormat displayFrame [attributes],)...
22734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *     options:
23734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *       -D #.## - End of test delay
24653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller *       -v - Verbose
25734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
26734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      graphic formats:
27734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGBA8888 (reference frame default)
28734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGBX8888
29734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGB888
30734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGB565
31734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        BGRA8888
32734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGBA5551
33734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        RGBA4444
34734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        YV12
35734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
36734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      displayFrame
37734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        [left, top, right, bottom]
38734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
39734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      attributes:
40734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        transform: none | fliph | flipv | rot90 | rot180 | rot270
41734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        blend: none | premult | coverage
42734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        color: [0.##, 0.##, 0.##]
43734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        alpha: 0.##
44734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        sourceDim: [width, height]
45734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        sourceCrop: [left, top, right, bottom]
46734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
47734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *      Example:
48734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        # White YV12 rectangle, with overlapping turquoise
49734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        #  RGBA8888 rectangle at 30%% (alpha: 0.7) transparency
50734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *        hwcRects -v -D 30.0 \
51734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *          YV12 [50, 80, 200, 300] transform: none \
52734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *            color: [1.0, 0.5, 0.5], \
53734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *          RGBA8888 [100, 150, 300, 400] blend: coverage \
54734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *            color: [0.251, 0.878, 0.816] alpha: 0.7 \
55734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *            sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]
56734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
57734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Description
58734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   Constructs a Hardware Composer (HWC) list of frames from
59734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   command-line specified parameters.  Then sends it to the HWC
60734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   be rendered.  The intended purpose of this tool is as a means to
61734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   reproduce and succinctly specify an observed HWC operation, with
62734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   no need to modify/compile a program.
63734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
64734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   The command-line syntax consists of a few standard command-line
65734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   options and then a description of one or more frames.  The frame
66734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   descriptions are separated from one another via a comma.  The
67734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   beginning of a frame description requires the specification
68734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   of the graphic format and then the display frame rectangle where
69734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   the frame will be displayed.  The display frame rectangle is
70734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   specified as follows, with the right and bottom coordinates being
71734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   exclusive values:
72734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
73734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *     [left, top, right, bottom]
74734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
75734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   After these two required parameters each frame description can
76734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   specify 1 or more optional attributes.  The name of each optional
77734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   attribute is preceded by a colon.  The current implementation
78734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   then requires white space after the colon and then the value of
79734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   the attribute is specified.  See the synopsis section above for
80734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   a list of attributes and the format of their expected value.
81734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */
82734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
83d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas#define LOG_TAG "hwcRectsTest"
84d1d16998adea189d5f24a774aa06e0e4e5f3e7ebAurimas Liutikas
85734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <algorithm>
86734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <assert.h>
87734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cerrno>
88734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cmath>
89734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cstdlib>
90734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <ctime>
91734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <istream>
92734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <libgen.h>
93734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <list>
94734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sched.h>
95734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sstream>
96734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <stdint.h>
97734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <string.h>
98734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <unistd.h>
99734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
100734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/syscall.h>
101734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/types.h>
102734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/wait.h>
103734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
104734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <EGL/egl.h>
105734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <EGL/eglext.h>
106734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <GLES2/gl2.h>
107734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <GLES2/gl2ext.h>
108734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
109734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <ui/GraphicBuffer.h>
110734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <utils/Log.h>
111734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <testUtil.h>
112734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
113734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <hardware/hwcomposer.h>
114734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
115734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <glTestLib.h>
116622cfadc8f0d294f875151fe1d8985e0553795eaMathias Agopian#include "hwcTestLib.h"
117734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
118734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerusing namespace std;
119734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerusing namespace android;
120734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
121734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Defaults
122734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst bool defaultVerbose = false;
123734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst float defaultEndDelay = 2.0; // Default delay after rendering graphics
124734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
125734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
126734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst int32_t    defaultTransform = 0;
127734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst uint32_t   defaultBlend = HWC_BLENDING_NONE;
128734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst ColorFract defaultColor(0.5, 0.5, 0.5);
129734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst float      defaultAlpha = 1.0; // Opaque
130734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst HwcTestDim defaultSourceDim(1, 1);
131734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
132734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};
133734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
134734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Defines
135734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define MAXCMD               200
136734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define CMD_STOP_FRAMEWORK   "stop 2>&1"
137734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define CMD_START_FRAMEWORK  "start 2>&1"
138734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
139734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Macros
140734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
141734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
142734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Local types
143734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass Rectangle {
144734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerpublic:
145734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    Rectangle() : format(defaultFormat), transform(defaultTransform),
146734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  blend(defaultBlend), color(defaultColor),
147734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  alpha(defaultAlpha), sourceDim(defaultSourceDim),
148734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  sourceCrop(defaultSourceCrop),
149734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  displayFrame(defaultDisplayFrame) {};
150734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
151734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    uint32_t     format;
152734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    uint32_t     transform;
153734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int32_t      blend;
154734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    ColorFract   color;
155734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    float        alpha;
156734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    HwcTestDim   sourceDim;
157734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    struct hwc_rect   sourceCrop;
158734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    struct hwc_rect   displayFrame;
159734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
160734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    sp<GraphicBuffer> texture;
161734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
162734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
163734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Globals
164734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerlist<Rectangle> rectangle;
165734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
166734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        GraphicBuffer::USAGE_SW_WRITE_RARELY;
1675880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hallstatic hwc_composer_device_1_t *hwcDevice;
168734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLDisplay dpy;
169734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLSurface surface;
170734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLint width, height;
171734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
172734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Function prototypes
173734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic Rectangle parseRect(string rectStr);
174734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid init(void);
175734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid printSyntax(const char *cmd);
176734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
177734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Command-line option settings
178734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic bool verbose = defaultVerbose;
179734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic float endDelay = defaultEndDelay;
180734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
181734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/*
182734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Main
183734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
184734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Performs the following high-level sequence of operations:
185734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
186734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   1. Parse command-line options
187734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
188734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   2. Stop framework
189734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
190734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   3. Initialization
191734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
192734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   4. Parse frame descriptions
193734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
194734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   5. Create HWC list from frame descriptions
195734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
196734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   6. Have HWC render the list description of the frames
197734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
198734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   7. Delay for amount of time given by endDelay
199734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
200734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   8. Start framework
201734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */
202734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerint
203734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillermain(int argc, char *argv[])
204734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
205734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int     rv, opt;
206734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    char   *chptr;
207734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string  str;
208734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    char cmd[MAXCMD];
209734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
210653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller    testSetLogCatTag(LOG_TAG);
211653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller
212734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Parse command line arguments
213734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while ((opt = getopt(argc, argv, "D:v?h")) != -1) {
214734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        switch (opt) {
215734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'D': // End of test delay
216734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            endDelay = strtod(optarg, &chptr);
217734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if ((*chptr != '\0') || (endDelay < 0.0)) {
218734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Invalid command-line specified end of test delay "
219734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           "of: %s", optarg);
220734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(1);
221734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
222734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            break;
223734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
224734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'v': // Verbose
225734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            verbose = true;
226734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            break;
227734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
228734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'h': // Help
229734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case '?':
230734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          default:
231734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            printSyntax(basename(argv[0]));
232734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(((optopt == 0) || (optopt == '?')) ? 0 : 2);
233734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
234734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
235734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
236734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Stop framework
237734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
238734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
239734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
240734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(3);
241734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
242734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testExecCmd(cmd);
243734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testDelay(1.0); // TODO - needs means to query whether asyncronous stop
244734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                    // framework operation has completed.  For now, just wait
245734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                    // a long time.
246734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
247734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    init();
248734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
249734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Parse rectangle descriptions
250734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int numOpen = 0; // Current number of unmatched <[
251734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string rectDesc(""); // String description of a single rectangle
252734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while (optind < argc) {
253734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        string argNext = string(argv[optind++]);
254734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
255734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (rectDesc.length()) { rectDesc += ' '; }
256734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        rectDesc += argNext;
257734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
258734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Count number of opening <[ and matching >]
259734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // At this point not worried about an opening character being
260734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // matched by it's corresponding closing character.  For example,
261734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // "<1.0, 2.0]" is incorrect because the opening < should be matched
262734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // with a closing >, instead of the closing ].  Such errors are
263734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // detected when the actual value is parsed.
264734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        for (unsigned int n1 = 0; n1 < argNext.length(); n1++) {
265734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            switch(argNext[n1]) {
266734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '[':
267734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '<':
268734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                numOpen++;
269734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                break;
270734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
271734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case ']':
272734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '>':
273734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                numOpen--;
274734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                break;
275734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
276734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
277734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Error anytime there is more closing then opening characters
278734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (numOpen < 0) {
279734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintI("Mismatched number of opening <[ with "
280734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           "closing >] in: %s", rectDesc.c_str());
281734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(4);
282734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
283734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
284734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
285734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Description of a rectangle is complete when all opening
286734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // <[ are closed with >] and the string ends with a comma or
287734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // there are no more args.
288734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if ((numOpen == 0) && rectDesc.length()
289734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            && ((rectDesc[rectDesc.length() - 1] == ',')
290734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                || (optind == argc))) {
291734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Remove trailing comma if it is present
292734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (rectDesc[rectDesc.length() - 1] == ',') {
293734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rectDesc.erase(rectDesc.length() - 1);
294734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
295734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
296734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Parse string description of rectangle
297734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            Rectangle rect = parseRect(rectDesc);
298734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
299734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Add to the list of rectangles
300734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rectangle.push_back(rect);
301734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
302734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Prepare for description of another rectangle
303734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rectDesc = string("");
304734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
305734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
306734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
307734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Create list of frames
308b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwc_display_contents_1_t *list;
309734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    list = hwcTestCreateLayerList(rectangle.size());
310734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (list == NULL) {
311734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("hwcTestCreateLayerList failed");
312734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(5);
313734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
314734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
3155880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall    hwc_layer_1_t *layer = &list->hwLayers[0];
316734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    for (std::list<Rectangle>::iterator it = rectangle.begin();
317734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller         it != rectangle.end(); ++it, ++layer) {
318734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->handle = it->texture->handle;
319734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->blending = it->blend;
320734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->transform = it->transform;
321734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->sourceCrop = it->sourceCrop;
322734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->displayFrame = it->displayFrame;
323734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
324734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->visibleRegionScreen.numRects = 1;
325734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->visibleRegionScreen.rects = &layer->displayFrame;
326734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
327734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
328734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Perform prepare operation
329734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
330b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwcDevice->prepare(hwcDevice, 1, &list);
331734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {
332734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintI("Post Prepare:");
333734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        hwcTestDisplayListPrepareModifiable(list);
334734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
335734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
336734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Turn off the geometry changed flag
337734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    list->flags &= ~HWC_GEOMETRY_CHANGED;
338734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
339734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Perform the set operation(s)
340734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {testPrintI("Set:"); }
341734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) { hwcTestDisplayListHandles(list); }
342b685c542836b93c99cd85053e07696406ea37adbJesse Hall    list->dpy = dpy;
343b685c542836b93c99cd85053e07696406ea37adbJesse Hall    list->sur = surface;
344b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwcDevice->set(hwcDevice, 1, &list);
345734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
346734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testDelay(endDelay);
347734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
348734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Start framework
349734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
350734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
351734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
352734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(6);
353734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
354734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testExecCmd(cmd);
355734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
356734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return 0;
357734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
358734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
359734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Parse string description of rectangle and add it to list of rectangles
360734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// to be rendered.
361734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic Rectangle parseRect(string rectStr)
362734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
363734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int rv;
364734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string str;
365734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    bool   error;
366734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    istringstream in(rectStr);
367734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    const struct hwcTestGraphicFormat *format;
368734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    Rectangle rect;
369734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
370734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Graphic Format
371734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    in >> str;
372734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (!in) {
373734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Error parsing format from: %s", rectStr.c_str());
374734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(20);
375734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
376734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    format = hwcTestGraphicFormatLookup(str.c_str());
377734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (format == NULL) {
378734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Unknown graphic format in: %s", rectStr.c_str());
379734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(21);
380734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
381734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.format = format->format;
382734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
383734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Display Frame
384734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.displayFrame = hwcTestParseHwcRect(in, error);
385734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (error) {
386734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid display frame in: %s", rectStr.c_str());
387734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(22);
388734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
389734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
390734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Set default sourceDim and sourceCrop based on size of display frame.
391734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Default is source size equal to the size of the display frame, with
392734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // the source crop being the entire size of the source frame.
393734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceDim = HwcTestDim(rect.displayFrame.right
394734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     - rect.displayFrame.left,
395734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                 rect.displayFrame.bottom
396734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     - rect.displayFrame.top);
397734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.left = 0;
398734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.top = 0;
399734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.right = rect.sourceDim.width();
400734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.bottom = rect.sourceDim.height();
401734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
402734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Optional settings
403734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while ((in.tellg() < (streampos) in.str().length())
404734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller           && (in.tellg() != (streampos) -1)) {
405734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        string attrName;
406734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
407734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        in >> attrName;
408734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (in.eof()) { break; }
409734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (!in) {
410734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            testPrintE("Error reading attribute name in: %s",
411734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                       rectStr.c_str());
412734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(23);
413734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
414734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
415734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Transform
416734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (attrName == "transform:") { // Transform
417734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            string str;
418734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
419734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> str;
420734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (str == "none") {
421734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = 0;
422734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "fliph") {
423734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_FLIP_H;
424734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "flipv") {
425734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_FLIP_V;
426734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot90") {
427734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_90;
428734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot180") {
429734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_180;
430734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot270") {
431734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_270;
432734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else {
433734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Unknown transform of \"%s\" in: %s", str.c_str(),
434734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
435734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(24);
436734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
437734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "blend:") { // Blend
438734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            string str;
439734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
440734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> str;
441734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (str == string("none")) {
442734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_NONE;
443734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "premult") {
444734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_PREMULT;
445734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "coverage") {
446734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_COVERAGE;
447734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else {
448734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Unknown blend of \"%s\" in: %s", str.c_str(),
449734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
450734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(25);
451734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
452734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "color:") { // Color
453734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rect.color = hwcTestParseColor(in, error);
454734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
455734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing color in: %s", rectStr.c_str());
456734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(26);
457734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
458734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "alpha:") { // Alpha
459734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> rect.alpha;
460734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (!in) {
461734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing value for alpha attribute in: %s",
462734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
463734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(27);
464734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
465734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "sourceDim:") { // Source Dimension
466734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller           rect.sourceDim = hwcTestParseDim(in, error);
467734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
468734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing source dimenision in: %s",
469734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
470734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(28);
471734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
472734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "sourceCrop:") { // Source Crop
473734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rect.sourceCrop = hwcTestParseHwcRect(in, error);
474734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
475734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing source crop in: %s",
476734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
477734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(29);
478734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
479734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else { // Unknown attribute
480734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            testPrintE("Unknown attribute of \"%s\" in: %s", attrName.c_str(),
481734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                       rectStr.c_str());
482734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(30);
483734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
484734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
485734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
486734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Validate
487734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (((uint32_t) rect.sourceCrop.left >= rect.sourceDim.width())
488734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.right > rect.sourceDim.width())
489734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.top >= rect.sourceDim.height())
490734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.bottom > rect.sourceDim.height())) {
491734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid source crop in: %s", rectStr.c_str());
492734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(31);
493734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
494734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rect.displayFrame.left >= width)
495734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.right > width)
496734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.top >= height)
497734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.bottom > height)) {
498734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid display frame in: %s", rectStr.c_str());
499734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(32);
500734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
501734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rect.alpha < 0.0) || (rect.alpha > 1.0)) {
502734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid alpha in: %s", rectStr.c_str());
503734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(33);
504734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
505734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
506734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Create source texture
507734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.texture = new GraphicBuffer(rect.sourceDim.width(),
508734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     rect.sourceDim.height(),
509734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     rect.format, texUsage);
510734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rv = rect.texture->initCheck()) != NO_ERROR) {
511734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("source texture initCheck failed, rv: %i", rv);
512734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("  %s", rectStr.c_str());
513734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
514734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
515734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
516734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Fill with uniform color
517734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestFillColor(rect.texture.get(), rect.color, rect.alpha);
518734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {
519734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintI("    buf: %p handle: %p format: %s width: %u height: %u "
520734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   "color: %s alpha: %f",
521734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   rect.texture.get(), rect.texture->handle, format->desc,
522734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   rect.sourceDim.width(), rect.sourceDim.height(),
523734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   string(rect.color).c_str(), rect.alpha);
524734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
525734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
526734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return rect;
527734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
528734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
529734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid init(void)
530734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
531734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Seed pseudo random number generator
532734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Needed so that the pad areas of frames are filled with a deterministic
533734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // pseudo random value.
534734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    srand48(0);
535734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
536734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
537734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
538734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestOpenHwc(&hwcDevice);
539734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
540734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
541734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid printSyntax(const char *cmd)
542734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
543734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("  %s [options] (graphicFormat displayFrame [attributes],)...",
544734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               cmd);
545734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    options:");
546734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      -D End of test delay");
547734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      -v Verbose");
548734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
549734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    graphic formats:");
550734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
551734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
552734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
553734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
554734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    displayFrame");
555734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      [left, top, right, bottom]");
556734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
557734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    attributes:");
558734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      transform: none | fliph | flipv | rot90 | rot180 "
559734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               " | rot270");
560734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      blend: none | premult | coverage");
561734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      color: [0.##, 0.##, 0.##]");
562734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      alpha: 0.##");
563734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      sourceDim: [width, height]");
564734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      sourceCrop: [left, top, right, bottom]");
565734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
566734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    Example:");
567734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      # White YV12 rectangle, with overlapping turquoise ");
568734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      #  RGBA8888 rectangle at 30%% (alpha: 0.7) transparency");
569734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      %s -v -D 30.0 \\", cmd);
570734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("        YV12 [50, 80, 200, 300] transform: none \\");
571734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          color: [1.0, 0.5, 0.5], \\");
572734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("        RGBA8888 [100, 150, 300, 400] blend: coverage \\");
573734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          color: [0.251, 0.878, 0.816] alpha: 0.7 \\");
574734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]");
575734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
576