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
83734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <algorithm>
84734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <assert.h>
85734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cerrno>
86734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cmath>
87734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <cstdlib>
88734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <ctime>
89734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <istream>
90734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <libgen.h>
91734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <list>
92734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sched.h>
93734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sstream>
94734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <stdint.h>
95734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <string.h>
96734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <unistd.h>
97734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
98734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/syscall.h>
99734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/types.h>
100734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <sys/wait.h>
101734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
102734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <EGL/egl.h>
103734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <EGL/eglext.h>
104734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <GLES2/gl2.h>
105734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <GLES2/gl2ext.h>
106734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
107734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <ui/FramebufferNativeWindow.h>
108734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <ui/GraphicBuffer.h>
109734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
110653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller#define LOG_TAG "hwcRectsTest"
111734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <utils/Log.h>
112734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <testUtil.h>
113734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
114734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <hardware/hwcomposer.h>
115734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
116734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#include <glTestLib.h>
117622cfadc8f0d294f875151fe1d8985e0553795eaMathias Agopian#include "hwcTestLib.h"
118734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
119734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerusing namespace std;
120734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerusing namespace android;
121734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
122734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Defaults
123734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst bool defaultVerbose = false;
124734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst float defaultEndDelay = 2.0; // Default delay after rendering graphics
125734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
126734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
127734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst int32_t    defaultTransform = 0;
128734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst uint32_t   defaultBlend = HWC_BLENDING_NONE;
129734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst ColorFract defaultColor(0.5, 0.5, 0.5);
130734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst float      defaultAlpha = 1.0; // Opaque
131734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst HwcTestDim defaultSourceDim(1, 1);
132734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
133734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerconst struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};
134734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
135734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Defines
136734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define MAXCMD               200
137734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define CMD_STOP_FRAMEWORK   "stop 2>&1"
138734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define CMD_START_FRAMEWORK  "start 2>&1"
139734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
140734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Macros
141734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array
142734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
143734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Local types
144734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerclass Rectangle {
145734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerpublic:
146734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    Rectangle() : format(defaultFormat), transform(defaultTransform),
147734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  blend(defaultBlend), color(defaultColor),
148734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  alpha(defaultAlpha), sourceDim(defaultSourceDim),
149734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  sourceCrop(defaultSourceCrop),
150734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                  displayFrame(defaultDisplayFrame) {};
151734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
152734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    uint32_t     format;
153734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    uint32_t     transform;
154734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int32_t      blend;
155734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    ColorFract   color;
156734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    float        alpha;
157734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    HwcTestDim   sourceDim;
158734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    struct hwc_rect   sourceCrop;
159734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    struct hwc_rect   displayFrame;
160734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
161734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    sp<GraphicBuffer> texture;
162734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller};
163734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
164734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Globals
165734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerlist<Rectangle> rectangle;
166734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
167734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        GraphicBuffer::USAGE_SW_WRITE_RARELY;
1685880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hallstatic hwc_composer_device_1_t *hwcDevice;
169734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLDisplay dpy;
170734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLSurface surface;
171734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic EGLint width, height;
172734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
173734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Function prototypes
174734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic Rectangle parseRect(string rectStr);
175734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid init(void);
176734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid printSyntax(const char *cmd);
177734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
178734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Command-line option settings
179734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic bool verbose = defaultVerbose;
180734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic float endDelay = defaultEndDelay;
181734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
182734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller/*
183734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Main
184734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
185734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller * Performs the following high-level sequence of operations:
186734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
187734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   1. Parse command-line options
188734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
189734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   2. Stop framework
190734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
191734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   3. Initialization
192734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
193734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   4. Parse frame descriptions
194734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
195734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   5. Create HWC list from frame descriptions
196734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
197734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   6. Have HWC render the list description of the frames
198734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
199734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   7. Delay for amount of time given by endDelay
200734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *
201734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller *   8. Start framework
202734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller */
203734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerint
204734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillermain(int argc, char *argv[])
205734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
206734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int     rv, opt;
207734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    char   *chptr;
208734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    bool    error;
209734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string  str;
210734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    char cmd[MAXCMD];
211734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
212653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller    testSetLogCatTag(LOG_TAG);
213653f81087920d479d8916a6ae6d2575dd80ed665Louis Huemiller
214734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Parse command line arguments
215734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while ((opt = getopt(argc, argv, "D:v?h")) != -1) {
216734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        switch (opt) {
217734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'D': // End of test delay
218734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            endDelay = strtod(optarg, &chptr);
219734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if ((*chptr != '\0') || (endDelay < 0.0)) {
220734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Invalid command-line specified end of test delay "
221734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           "of: %s", optarg);
222734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(1);
223734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
224734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            break;
225734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
226734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'v': // Verbose
227734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            verbose = true;
228734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            break;
229734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
230734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case 'h': // Help
231734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          case '?':
232734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller          default:
233734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            printSyntax(basename(argv[0]));
234734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(((optopt == 0) || (optopt == '?')) ? 0 : 2);
235734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
236734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
237734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
238734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Stop framework
239734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
240734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
241734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
242734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(3);
243734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
244734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testExecCmd(cmd);
245734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testDelay(1.0); // TODO - needs means to query whether asyncronous stop
246734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                    // framework operation has completed.  For now, just wait
247734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                    // a long time.
248734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
249734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    init();
250734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
251734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Parse rectangle descriptions
252734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int numOpen = 0; // Current number of unmatched <[
253734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string rectDesc(""); // String description of a single rectangle
254734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while (optind < argc) {
255734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        string argNext = string(argv[optind++]);
256734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
257734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (rectDesc.length()) { rectDesc += ' '; }
258734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        rectDesc += argNext;
259734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
260734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Count number of opening <[ and matching >]
261734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // At this point not worried about an opening character being
262734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // matched by it's corresponding closing character.  For example,
263734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // "<1.0, 2.0]" is incorrect because the opening < should be matched
264734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // with a closing >, instead of the closing ].  Such errors are
265734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // detected when the actual value is parsed.
266734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        for (unsigned int n1 = 0; n1 < argNext.length(); n1++) {
267734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            switch(argNext[n1]) {
268734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '[':
269734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '<':
270734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                numOpen++;
271734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                break;
272734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
273734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case ']':
274734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller              case '>':
275734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                numOpen--;
276734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                break;
277734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
278734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
279734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Error anytime there is more closing then opening characters
280734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (numOpen < 0) {
281734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintI("Mismatched number of opening <[ with "
282734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           "closing >] in: %s", rectDesc.c_str());
283734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(4);
284734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
285734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
286734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
287734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Description of a rectangle is complete when all opening
288734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // <[ are closed with >] and the string ends with a comma or
289734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // there are no more args.
290734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if ((numOpen == 0) && rectDesc.length()
291734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            && ((rectDesc[rectDesc.length() - 1] == ',')
292734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                || (optind == argc))) {
293734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Remove trailing comma if it is present
294734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (rectDesc[rectDesc.length() - 1] == ',') {
295734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rectDesc.erase(rectDesc.length() - 1);
296734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
297734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
298734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Parse string description of rectangle
299734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            Rectangle rect = parseRect(rectDesc);
300734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
301734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Add to the list of rectangles
302734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rectangle.push_back(rect);
303734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
304734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            // Prepare for description of another rectangle
305734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rectDesc = string("");
306734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
307734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
308734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
309734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Create list of frames
310b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwc_display_contents_1_t *list;
311734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    list = hwcTestCreateLayerList(rectangle.size());
312734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (list == NULL) {
313734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("hwcTestCreateLayerList failed");
314734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(5);
315734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
316734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
3175880cc573823148237eac9ab7bc586b8e4eb7160Jesse Hall    hwc_layer_1_t *layer = &list->hwLayers[0];
318734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    for (std::list<Rectangle>::iterator it = rectangle.begin();
319734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller         it != rectangle.end(); ++it, ++layer) {
320734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->handle = it->texture->handle;
321734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->blending = it->blend;
322734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->transform = it->transform;
323734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->sourceCrop = it->sourceCrop;
324734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->displayFrame = it->displayFrame;
325734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
326734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->visibleRegionScreen.numRects = 1;
327734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        layer->visibleRegionScreen.rects = &layer->displayFrame;
328734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
329734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
330734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Perform prepare operation
331734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
332b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwcDevice->prepare(hwcDevice, 1, &list);
333734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {
334734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintI("Post Prepare:");
335734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        hwcTestDisplayListPrepareModifiable(list);
336734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
337734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
338734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Turn off the geometry changed flag
339734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    list->flags &= ~HWC_GEOMETRY_CHANGED;
340734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
341734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Perform the set operation(s)
342734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {testPrintI("Set:"); }
343734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) { hwcTestDisplayListHandles(list); }
344b685c542836b93c99cd85053e07696406ea37adbJesse Hall    list->dpy = dpy;
345b685c542836b93c99cd85053e07696406ea37adbJesse Hall    list->sur = surface;
346b685c542836b93c99cd85053e07696406ea37adbJesse Hall    hwcDevice->set(hwcDevice, 1, &list);
347734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
348734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testDelay(endDelay);
349734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
350734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Start framework
351734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
352734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (rv >= (signed) sizeof(cmd) - 1) {
353734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
354734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(6);
355734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
356734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testExecCmd(cmd);
357734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
358734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return 0;
359734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
360734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
361734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// Parse string description of rectangle and add it to list of rectangles
362734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller// to be rendered.
363734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillerstatic Rectangle parseRect(string rectStr)
364734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
365734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    int rv;
366734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    string str;
367734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    bool   error;
368734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    istringstream in(rectStr);
369734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    const struct hwcTestGraphicFormat *format;
370734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    Rectangle rect;
371734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    struct hwc_rect hwcRect;
372734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
373734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Graphic Format
374734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    in >> str;
375734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (!in) {
376734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Error parsing format from: %s", rectStr.c_str());
377734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(20);
378734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
379734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    format = hwcTestGraphicFormatLookup(str.c_str());
380734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (format == NULL) {
381734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Unknown graphic format in: %s", rectStr.c_str());
382734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(21);
383734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
384734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.format = format->format;
385734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
386734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Display Frame
387734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.displayFrame = hwcTestParseHwcRect(in, error);
388734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (error) {
389734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid display frame in: %s", rectStr.c_str());
390734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(22);
391734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
392734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
393734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Set default sourceDim and sourceCrop based on size of display frame.
394734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Default is source size equal to the size of the display frame, with
395734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // the source crop being the entire size of the source frame.
396734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceDim = HwcTestDim(rect.displayFrame.right
397734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     - rect.displayFrame.left,
398734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                 rect.displayFrame.bottom
399734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     - rect.displayFrame.top);
400734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.left = 0;
401734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.top = 0;
402734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.right = rect.sourceDim.width();
403734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.sourceCrop.bottom = rect.sourceDim.height();
404734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
405734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Optional settings
406734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    while ((in.tellg() < (streampos) in.str().length())
407734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller           && (in.tellg() != (streampos) -1)) {
408734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        string attrName;
409734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
410734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        in >> attrName;
411734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (in.eof()) { break; }
412734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (!in) {
413734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            testPrintE("Error reading attribute name in: %s",
414734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                       rectStr.c_str());
415734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(23);
416734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
417734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
418734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        // Transform
419734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        if (attrName == "transform:") { // Transform
420734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            string str;
421734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
422734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> str;
423734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (str == "none") {
424734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = 0;
425734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "fliph") {
426734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_FLIP_H;
427734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "flipv") {
428734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_FLIP_V;
429734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot90") {
430734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_90;
431734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot180") {
432734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_180;
433734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "rot270") {
434734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.transform = HWC_TRANSFORM_ROT_270;
435734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else {
436734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Unknown transform of \"%s\" in: %s", str.c_str(),
437734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
438734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(24);
439734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
440734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "blend:") { // Blend
441734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            string str;
442734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
443734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> str;
444734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (str == string("none")) {
445734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_NONE;
446734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "premult") {
447734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_PREMULT;
448734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else if (str == "coverage") {
449734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                rect.blend = HWC_BLENDING_COVERAGE;
450734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            } else {
451734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Unknown blend of \"%s\" in: %s", str.c_str(),
452734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
453734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(25);
454734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
455734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "color:") { // Color
456734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rect.color = hwcTestParseColor(in, error);
457734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
458734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing color in: %s", rectStr.c_str());
459734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(26);
460734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
461734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "alpha:") { // Alpha
462734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            in >> rect.alpha;
463734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (!in) {
464734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing value for alpha attribute in: %s",
465734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
466734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(27);
467734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
468734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "sourceDim:") { // Source Dimension
469734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller           rect.sourceDim = hwcTestParseDim(in, error);
470734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
471734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing source dimenision in: %s",
472734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
473734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(28);
474734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
475734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else if (attrName == "sourceCrop:") { // Source Crop
476734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            rect.sourceCrop = hwcTestParseHwcRect(in, error);
477734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            if (error) {
478734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                testPrintE("Error parsing source crop in: %s",
479734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                           rectStr.c_str());
480734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                exit(29);
481734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            }
482734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        } else { // Unknown attribute
483734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            testPrintE("Unknown attribute of \"%s\" in: %s", attrName.c_str(),
484734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                       rectStr.c_str());
485734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller            exit(30);
486734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        }
487734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
488734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
489734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Validate
490734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (((uint32_t) rect.sourceCrop.left >= rect.sourceDim.width())
491734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.right > rect.sourceDim.width())
492734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.top >= rect.sourceDim.height())
493734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || ((uint32_t) rect.sourceCrop.bottom > rect.sourceDim.height())) {
494734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid source crop in: %s", rectStr.c_str());
495734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(31);
496734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
497734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rect.displayFrame.left >= width)
498734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.right > width)
499734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.top >= height)
500734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        || (rect.displayFrame.bottom > height)) {
501734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid display frame in: %s", rectStr.c_str());
502734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(32);
503734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
504734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rect.alpha < 0.0) || (rect.alpha > 1.0)) {
505734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("Invalid alpha in: %s", rectStr.c_str());
506734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        exit(33);
507734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
508734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
509734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Create source texture
510734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    rect.texture = new GraphicBuffer(rect.sourceDim.width(),
511734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     rect.sourceDim.height(),
512734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                                     rect.format, texUsage);
513734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if ((rv = rect.texture->initCheck()) != NO_ERROR) {
514734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("source texture initCheck failed, rv: %i", rv);
515734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("  %s", rectStr.c_str());
516734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
517734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
518734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
519734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Fill with uniform color
520734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestFillColor(rect.texture.get(), rect.color, rect.alpha);
521734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    if (verbose) {
522734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintI("    buf: %p handle: %p format: %s width: %u height: %u "
523734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   "color: %s alpha: %f",
524734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   rect.texture.get(), rect.texture->handle, format->desc,
525734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   rect.sourceDim.width(), rect.sourceDim.height(),
526734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller                   string(rect.color).c_str(), rect.alpha);
527734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
528734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
529734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    return rect;
530734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
531734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
532734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid init(void)
533734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
534734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Seed pseudo random number generator
535734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // Needed so that the pad areas of frames are filled with a deterministic
536734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    // pseudo random value.
537734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    srand48(0);
538734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
539734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
540734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
541734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    hwcTestOpenHwc(&hwcDevice);
542734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
543734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller
544734d8d898c6b0b315e431b231cc6759514da361bLouis Huemillervoid printSyntax(const char *cmd)
545734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller{
546734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("  %s [options] (graphicFormat displayFrame [attributes],)...",
547734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               cmd);
548734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    options:");
549734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      -D End of test delay");
550734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      -v Verbose");
551734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
552734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    graphic formats:");
553734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
554734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
555734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    }
556734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
557734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    displayFrame");
558734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      [left, top, right, bottom]");
559734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
560734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    attributes:");
561734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      transform: none | fliph | flipv | rot90 | rot180 "
562734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller               " | rot270");
563734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      blend: none | premult | coverage");
564734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      color: [0.##, 0.##, 0.##]");
565734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      alpha: 0.##");
566734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      sourceDim: [width, height]");
567734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      sourceCrop: [left, top, right, bottom]");
568734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("");
569734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("    Example:");
570734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      # White YV12 rectangle, with overlapping turquoise ");
571734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      #  RGBA8888 rectangle at 30%% (alpha: 0.7) transparency");
572734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("      %s -v -D 30.0 \\", cmd);
573734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("        YV12 [50, 80, 200, 300] transform: none \\");
574734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          color: [1.0, 0.5, 0.5], \\");
575734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("        RGBA8888 [100, 150, 300, 400] blend: coverage \\");
576734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          color: [0.251, 0.878, 0.816] alpha: 0.7 \\");
577734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller    testPrintE("          sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]");
578734d8d898c6b0b315e431b231cc6759514da361bLouis Huemiller}
579