1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker */
16*38e8c45fSAndroid Build Coastguard Worker
17*38e8c45fSAndroid Build Coastguard Worker /*
18*38e8c45fSAndroid Build Coastguard Worker * Hardware Composer Rectangles
19*38e8c45fSAndroid Build Coastguard Worker *
20*38e8c45fSAndroid Build Coastguard Worker * Synopsis
21*38e8c45fSAndroid Build Coastguard Worker * hwcRects [options] (graphicFormat displayFrame [attributes],)...
22*38e8c45fSAndroid Build Coastguard Worker * options:
23*38e8c45fSAndroid Build Coastguard Worker * -D #.## - End of test delay
24*38e8c45fSAndroid Build Coastguard Worker * -v - Verbose
25*38e8c45fSAndroid Build Coastguard Worker *
26*38e8c45fSAndroid Build Coastguard Worker * graphic formats:
27*38e8c45fSAndroid Build Coastguard Worker * RGBA8888 (reference frame default)
28*38e8c45fSAndroid Build Coastguard Worker * RGBX8888
29*38e8c45fSAndroid Build Coastguard Worker * RGB888
30*38e8c45fSAndroid Build Coastguard Worker * RGB565
31*38e8c45fSAndroid Build Coastguard Worker * BGRA8888
32*38e8c45fSAndroid Build Coastguard Worker * RGBA5551
33*38e8c45fSAndroid Build Coastguard Worker * RGBA4444
34*38e8c45fSAndroid Build Coastguard Worker * YV12
35*38e8c45fSAndroid Build Coastguard Worker *
36*38e8c45fSAndroid Build Coastguard Worker * displayFrame
37*38e8c45fSAndroid Build Coastguard Worker * [left, top, right, bottom]
38*38e8c45fSAndroid Build Coastguard Worker *
39*38e8c45fSAndroid Build Coastguard Worker * attributes:
40*38e8c45fSAndroid Build Coastguard Worker * transform: none | fliph | flipv | rot90 | rot180 | rot270
41*38e8c45fSAndroid Build Coastguard Worker * blend: none | premult | coverage
42*38e8c45fSAndroid Build Coastguard Worker * color: [0.##, 0.##, 0.##]
43*38e8c45fSAndroid Build Coastguard Worker * alpha: 0.##
44*38e8c45fSAndroid Build Coastguard Worker * sourceDim: [width, height]
45*38e8c45fSAndroid Build Coastguard Worker * sourceCrop: [left, top, right, bottom]
46*38e8c45fSAndroid Build Coastguard Worker *
47*38e8c45fSAndroid Build Coastguard Worker * Example:
48*38e8c45fSAndroid Build Coastguard Worker * # White YV12 rectangle, with overlapping turquoise
49*38e8c45fSAndroid Build Coastguard Worker * # RGBA8888 rectangle at 30%% (alpha: 0.7) transparency
50*38e8c45fSAndroid Build Coastguard Worker * hwcRects -v -D 30.0 \
51*38e8c45fSAndroid Build Coastguard Worker * YV12 [50, 80, 200, 300] transform: none \
52*38e8c45fSAndroid Build Coastguard Worker * color: [1.0, 0.5, 0.5], \
53*38e8c45fSAndroid Build Coastguard Worker * RGBA8888 [100, 150, 300, 400] blend: coverage \
54*38e8c45fSAndroid Build Coastguard Worker * color: [0.251, 0.878, 0.816] alpha: 0.7 \
55*38e8c45fSAndroid Build Coastguard Worker * sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]
56*38e8c45fSAndroid Build Coastguard Worker *
57*38e8c45fSAndroid Build Coastguard Worker * Description
58*38e8c45fSAndroid Build Coastguard Worker * Constructs a Hardware Composer (HWC) list of frames from
59*38e8c45fSAndroid Build Coastguard Worker * command-line specified parameters. Then sends it to the HWC
60*38e8c45fSAndroid Build Coastguard Worker * be rendered. The intended purpose of this tool is as a means to
61*38e8c45fSAndroid Build Coastguard Worker * reproduce and succinctly specify an observed HWC operation, with
62*38e8c45fSAndroid Build Coastguard Worker * no need to modify/compile a program.
63*38e8c45fSAndroid Build Coastguard Worker *
64*38e8c45fSAndroid Build Coastguard Worker * The command-line syntax consists of a few standard command-line
65*38e8c45fSAndroid Build Coastguard Worker * options and then a description of one or more frames. The frame
66*38e8c45fSAndroid Build Coastguard Worker * descriptions are separated from one another via a comma. The
67*38e8c45fSAndroid Build Coastguard Worker * beginning of a frame description requires the specification
68*38e8c45fSAndroid Build Coastguard Worker * of the graphic format and then the display frame rectangle where
69*38e8c45fSAndroid Build Coastguard Worker * the frame will be displayed. The display frame rectangle is
70*38e8c45fSAndroid Build Coastguard Worker * specified as follows, with the right and bottom coordinates being
71*38e8c45fSAndroid Build Coastguard Worker * exclusive values:
72*38e8c45fSAndroid Build Coastguard Worker *
73*38e8c45fSAndroid Build Coastguard Worker * [left, top, right, bottom]
74*38e8c45fSAndroid Build Coastguard Worker *
75*38e8c45fSAndroid Build Coastguard Worker * After these two required parameters each frame description can
76*38e8c45fSAndroid Build Coastguard Worker * specify 1 or more optional attributes. The name of each optional
77*38e8c45fSAndroid Build Coastguard Worker * attribute is preceded by a colon. The current implementation
78*38e8c45fSAndroid Build Coastguard Worker * then requires white space after the colon and then the value of
79*38e8c45fSAndroid Build Coastguard Worker * the attribute is specified. See the synopsis section above for
80*38e8c45fSAndroid Build Coastguard Worker * a list of attributes and the format of their expected value.
81*38e8c45fSAndroid Build Coastguard Worker */
82*38e8c45fSAndroid Build Coastguard Worker
83*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "hwcRectsTest"
84*38e8c45fSAndroid Build Coastguard Worker
85*38e8c45fSAndroid Build Coastguard Worker #include <algorithm>
86*38e8c45fSAndroid Build Coastguard Worker #include <assert.h>
87*38e8c45fSAndroid Build Coastguard Worker #include <cerrno>
88*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
89*38e8c45fSAndroid Build Coastguard Worker #include <cstdlib>
90*38e8c45fSAndroid Build Coastguard Worker #include <ctime>
91*38e8c45fSAndroid Build Coastguard Worker #include <istream>
92*38e8c45fSAndroid Build Coastguard Worker #include <libgen.h>
93*38e8c45fSAndroid Build Coastguard Worker #include <list>
94*38e8c45fSAndroid Build Coastguard Worker #include <sched.h>
95*38e8c45fSAndroid Build Coastguard Worker #include <sstream>
96*38e8c45fSAndroid Build Coastguard Worker #include <stdint.h>
97*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
98*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
99*38e8c45fSAndroid Build Coastguard Worker
100*38e8c45fSAndroid Build Coastguard Worker #include <sys/syscall.h>
101*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
102*38e8c45fSAndroid Build Coastguard Worker #include <sys/wait.h>
103*38e8c45fSAndroid Build Coastguard Worker
104*38e8c45fSAndroid Build Coastguard Worker #include <EGL/egl.h>
105*38e8c45fSAndroid Build Coastguard Worker #include <EGL/eglext.h>
106*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
107*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2ext.h>
108*38e8c45fSAndroid Build Coastguard Worker
109*38e8c45fSAndroid Build Coastguard Worker #include <ui/GraphicBuffer.h>
110*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
111*38e8c45fSAndroid Build Coastguard Worker #include <testUtil.h>
112*38e8c45fSAndroid Build Coastguard Worker
113*38e8c45fSAndroid Build Coastguard Worker #include <hardware/hwcomposer.h>
114*38e8c45fSAndroid Build Coastguard Worker
115*38e8c45fSAndroid Build Coastguard Worker #include <glTestLib.h>
116*38e8c45fSAndroid Build Coastguard Worker #include "hwcTestLib.h"
117*38e8c45fSAndroid Build Coastguard Worker
118*38e8c45fSAndroid Build Coastguard Worker using namespace std;
119*38e8c45fSAndroid Build Coastguard Worker using namespace android;
120*38e8c45fSAndroid Build Coastguard Worker
121*38e8c45fSAndroid Build Coastguard Worker // Defaults
122*38e8c45fSAndroid Build Coastguard Worker const bool defaultVerbose = false;
123*38e8c45fSAndroid Build Coastguard Worker const float defaultEndDelay = 2.0; // Default delay after rendering graphics
124*38e8c45fSAndroid Build Coastguard Worker
125*38e8c45fSAndroid Build Coastguard Worker const uint32_t defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
126*38e8c45fSAndroid Build Coastguard Worker const int32_t defaultTransform = 0;
127*38e8c45fSAndroid Build Coastguard Worker const uint32_t defaultBlend = HWC_BLENDING_NONE;
128*38e8c45fSAndroid Build Coastguard Worker const ColorFract defaultColor(0.5, 0.5, 0.5);
129*38e8c45fSAndroid Build Coastguard Worker const float defaultAlpha = 1.0; // Opaque
130*38e8c45fSAndroid Build Coastguard Worker const HwcTestDim defaultSourceDim(1, 1);
131*38e8c45fSAndroid Build Coastguard Worker const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
132*38e8c45fSAndroid Build Coastguard Worker const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};
133*38e8c45fSAndroid Build Coastguard Worker
134*38e8c45fSAndroid Build Coastguard Worker // Defines
135*38e8c45fSAndroid Build Coastguard Worker #define MAXCMD 200
136*38e8c45fSAndroid Build Coastguard Worker #define CMD_STOP_FRAMEWORK "stop 2>&1"
137*38e8c45fSAndroid Build Coastguard Worker #define CMD_START_FRAMEWORK "start 2>&1"
138*38e8c45fSAndroid Build Coastguard Worker
139*38e8c45fSAndroid Build Coastguard Worker // Macros
140*38e8c45fSAndroid Build Coastguard Worker #define NUMA(a) (sizeof(a) / sizeof((a)[0])) // Num elements in an array
141*38e8c45fSAndroid Build Coastguard Worker
142*38e8c45fSAndroid Build Coastguard Worker // Local types
143*38e8c45fSAndroid Build Coastguard Worker class Rectangle {
144*38e8c45fSAndroid Build Coastguard Worker public:
Rectangle()145*38e8c45fSAndroid Build Coastguard Worker Rectangle() : format(defaultFormat), transform(defaultTransform),
146*38e8c45fSAndroid Build Coastguard Worker blend(defaultBlend), color(defaultColor),
147*38e8c45fSAndroid Build Coastguard Worker alpha(defaultAlpha), sourceDim(defaultSourceDim),
148*38e8c45fSAndroid Build Coastguard Worker sourceCrop(defaultSourceCrop),
149*38e8c45fSAndroid Build Coastguard Worker displayFrame(defaultDisplayFrame) {};
150*38e8c45fSAndroid Build Coastguard Worker
151*38e8c45fSAndroid Build Coastguard Worker uint32_t format;
152*38e8c45fSAndroid Build Coastguard Worker uint32_t transform;
153*38e8c45fSAndroid Build Coastguard Worker int32_t blend;
154*38e8c45fSAndroid Build Coastguard Worker ColorFract color;
155*38e8c45fSAndroid Build Coastguard Worker float alpha;
156*38e8c45fSAndroid Build Coastguard Worker HwcTestDim sourceDim;
157*38e8c45fSAndroid Build Coastguard Worker struct hwc_rect sourceCrop;
158*38e8c45fSAndroid Build Coastguard Worker struct hwc_rect displayFrame;
159*38e8c45fSAndroid Build Coastguard Worker
160*38e8c45fSAndroid Build Coastguard Worker sp<GraphicBuffer> texture;
161*38e8c45fSAndroid Build Coastguard Worker };
162*38e8c45fSAndroid Build Coastguard Worker
163*38e8c45fSAndroid Build Coastguard Worker // Globals
164*38e8c45fSAndroid Build Coastguard Worker list<Rectangle> rectangle;
165*38e8c45fSAndroid Build Coastguard Worker static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
166*38e8c45fSAndroid Build Coastguard Worker GraphicBuffer::USAGE_SW_WRITE_RARELY;
167*38e8c45fSAndroid Build Coastguard Worker static hwc_composer_device_1_t *hwcDevice;
168*38e8c45fSAndroid Build Coastguard Worker static EGLDisplay dpy;
169*38e8c45fSAndroid Build Coastguard Worker static EGLSurface surface;
170*38e8c45fSAndroid Build Coastguard Worker static EGLint width, height;
171*38e8c45fSAndroid Build Coastguard Worker
172*38e8c45fSAndroid Build Coastguard Worker // Function prototypes
173*38e8c45fSAndroid Build Coastguard Worker static Rectangle parseRect(const string& rectStr);
174*38e8c45fSAndroid Build Coastguard Worker void init(void);
175*38e8c45fSAndroid Build Coastguard Worker void printSyntax(const char *cmd);
176*38e8c45fSAndroid Build Coastguard Worker
177*38e8c45fSAndroid Build Coastguard Worker // Command-line option settings
178*38e8c45fSAndroid Build Coastguard Worker static bool verbose = defaultVerbose;
179*38e8c45fSAndroid Build Coastguard Worker static float endDelay = defaultEndDelay;
180*38e8c45fSAndroid Build Coastguard Worker
181*38e8c45fSAndroid Build Coastguard Worker /*
182*38e8c45fSAndroid Build Coastguard Worker * Main
183*38e8c45fSAndroid Build Coastguard Worker *
184*38e8c45fSAndroid Build Coastguard Worker * Performs the following high-level sequence of operations:
185*38e8c45fSAndroid Build Coastguard Worker *
186*38e8c45fSAndroid Build Coastguard Worker * 1. Parse command-line options
187*38e8c45fSAndroid Build Coastguard Worker *
188*38e8c45fSAndroid Build Coastguard Worker * 2. Stop framework
189*38e8c45fSAndroid Build Coastguard Worker *
190*38e8c45fSAndroid Build Coastguard Worker * 3. Initialization
191*38e8c45fSAndroid Build Coastguard Worker *
192*38e8c45fSAndroid Build Coastguard Worker * 4. Parse frame descriptions
193*38e8c45fSAndroid Build Coastguard Worker *
194*38e8c45fSAndroid Build Coastguard Worker * 5. Create HWC list from frame descriptions
195*38e8c45fSAndroid Build Coastguard Worker *
196*38e8c45fSAndroid Build Coastguard Worker * 6. Have HWC render the list description of the frames
197*38e8c45fSAndroid Build Coastguard Worker *
198*38e8c45fSAndroid Build Coastguard Worker * 7. Delay for amount of time given by endDelay
199*38e8c45fSAndroid Build Coastguard Worker *
200*38e8c45fSAndroid Build Coastguard Worker * 8. Start framework
201*38e8c45fSAndroid Build Coastguard Worker */
202*38e8c45fSAndroid Build Coastguard Worker int
main(int argc,char * argv[])203*38e8c45fSAndroid Build Coastguard Worker main(int argc, char *argv[])
204*38e8c45fSAndroid Build Coastguard Worker {
205*38e8c45fSAndroid Build Coastguard Worker int rv, opt;
206*38e8c45fSAndroid Build Coastguard Worker char *chptr;
207*38e8c45fSAndroid Build Coastguard Worker string str;
208*38e8c45fSAndroid Build Coastguard Worker char cmd[MAXCMD];
209*38e8c45fSAndroid Build Coastguard Worker
210*38e8c45fSAndroid Build Coastguard Worker testSetLogCatTag(LOG_TAG);
211*38e8c45fSAndroid Build Coastguard Worker
212*38e8c45fSAndroid Build Coastguard Worker // Parse command line arguments
213*38e8c45fSAndroid Build Coastguard Worker while ((opt = getopt(argc, argv, "D:v?h")) != -1) {
214*38e8c45fSAndroid Build Coastguard Worker switch (opt) {
215*38e8c45fSAndroid Build Coastguard Worker case 'D': // End of test delay
216*38e8c45fSAndroid Build Coastguard Worker endDelay = strtod(optarg, &chptr);
217*38e8c45fSAndroid Build Coastguard Worker if ((*chptr != '\0') || (endDelay < 0.0)) {
218*38e8c45fSAndroid Build Coastguard Worker testPrintE("Invalid command-line specified end of test delay "
219*38e8c45fSAndroid Build Coastguard Worker "of: %s", optarg);
220*38e8c45fSAndroid Build Coastguard Worker exit(1);
221*38e8c45fSAndroid Build Coastguard Worker }
222*38e8c45fSAndroid Build Coastguard Worker break;
223*38e8c45fSAndroid Build Coastguard Worker
224*38e8c45fSAndroid Build Coastguard Worker case 'v': // Verbose
225*38e8c45fSAndroid Build Coastguard Worker verbose = true;
226*38e8c45fSAndroid Build Coastguard Worker break;
227*38e8c45fSAndroid Build Coastguard Worker
228*38e8c45fSAndroid Build Coastguard Worker case 'h': // Help
229*38e8c45fSAndroid Build Coastguard Worker case '?':
230*38e8c45fSAndroid Build Coastguard Worker default:
231*38e8c45fSAndroid Build Coastguard Worker printSyntax(basename(argv[0]));
232*38e8c45fSAndroid Build Coastguard Worker exit(((optopt == 0) || (optopt == '?')) ? 0 : 2);
233*38e8c45fSAndroid Build Coastguard Worker }
234*38e8c45fSAndroid Build Coastguard Worker }
235*38e8c45fSAndroid Build Coastguard Worker
236*38e8c45fSAndroid Build Coastguard Worker // Stop framework
237*38e8c45fSAndroid Build Coastguard Worker rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
238*38e8c45fSAndroid Build Coastguard Worker if (rv >= (signed) sizeof(cmd) - 1) {
239*38e8c45fSAndroid Build Coastguard Worker testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
240*38e8c45fSAndroid Build Coastguard Worker exit(3);
241*38e8c45fSAndroid Build Coastguard Worker }
242*38e8c45fSAndroid Build Coastguard Worker testExecCmd(cmd);
243*38e8c45fSAndroid Build Coastguard Worker testDelay(1.0); // TODO - needs means to query whether asyncronous stop
244*38e8c45fSAndroid Build Coastguard Worker // framework operation has completed. For now, just wait
245*38e8c45fSAndroid Build Coastguard Worker // a long time.
246*38e8c45fSAndroid Build Coastguard Worker
247*38e8c45fSAndroid Build Coastguard Worker init();
248*38e8c45fSAndroid Build Coastguard Worker
249*38e8c45fSAndroid Build Coastguard Worker // Parse rectangle descriptions
250*38e8c45fSAndroid Build Coastguard Worker int numOpen = 0; // Current number of unmatched <[
251*38e8c45fSAndroid Build Coastguard Worker string rectDesc(""); // String description of a single rectangle
252*38e8c45fSAndroid Build Coastguard Worker while (optind < argc) {
253*38e8c45fSAndroid Build Coastguard Worker string argNext = string(argv[optind++]);
254*38e8c45fSAndroid Build Coastguard Worker
255*38e8c45fSAndroid Build Coastguard Worker if (rectDesc.length()) { rectDesc += ' '; }
256*38e8c45fSAndroid Build Coastguard Worker rectDesc += argNext;
257*38e8c45fSAndroid Build Coastguard Worker
258*38e8c45fSAndroid Build Coastguard Worker // Count number of opening <[ and matching >]
259*38e8c45fSAndroid Build Coastguard Worker // At this point not worried about an opening character being
260*38e8c45fSAndroid Build Coastguard Worker // matched by it's corresponding closing character. For example,
261*38e8c45fSAndroid Build Coastguard Worker // "<1.0, 2.0]" is incorrect because the opening < should be matched
262*38e8c45fSAndroid Build Coastguard Worker // with a closing >, instead of the closing ]. Such errors are
263*38e8c45fSAndroid Build Coastguard Worker // detected when the actual value is parsed.
264*38e8c45fSAndroid Build Coastguard Worker for (unsigned int n1 = 0; n1 < argNext.length(); n1++) {
265*38e8c45fSAndroid Build Coastguard Worker switch(argNext[n1]) {
266*38e8c45fSAndroid Build Coastguard Worker case '[':
267*38e8c45fSAndroid Build Coastguard Worker case '<':
268*38e8c45fSAndroid Build Coastguard Worker numOpen++;
269*38e8c45fSAndroid Build Coastguard Worker break;
270*38e8c45fSAndroid Build Coastguard Worker
271*38e8c45fSAndroid Build Coastguard Worker case ']':
272*38e8c45fSAndroid Build Coastguard Worker case '>':
273*38e8c45fSAndroid Build Coastguard Worker numOpen--;
274*38e8c45fSAndroid Build Coastguard Worker break;
275*38e8c45fSAndroid Build Coastguard Worker }
276*38e8c45fSAndroid Build Coastguard Worker
277*38e8c45fSAndroid Build Coastguard Worker // Error anytime there is more closing then opening characters
278*38e8c45fSAndroid Build Coastguard Worker if (numOpen < 0) {
279*38e8c45fSAndroid Build Coastguard Worker testPrintI("Mismatched number of opening <[ with "
280*38e8c45fSAndroid Build Coastguard Worker "closing >] in: %s", rectDesc.c_str());
281*38e8c45fSAndroid Build Coastguard Worker exit(4);
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker }
284*38e8c45fSAndroid Build Coastguard Worker
285*38e8c45fSAndroid Build Coastguard Worker // Description of a rectangle is complete when all opening
286*38e8c45fSAndroid Build Coastguard Worker // <[ are closed with >] and the string ends with a comma or
287*38e8c45fSAndroid Build Coastguard Worker // there are no more args.
288*38e8c45fSAndroid Build Coastguard Worker if ((numOpen == 0) && rectDesc.length()
289*38e8c45fSAndroid Build Coastguard Worker && ((rectDesc[rectDesc.length() - 1] == ',')
290*38e8c45fSAndroid Build Coastguard Worker || (optind == argc))) {
291*38e8c45fSAndroid Build Coastguard Worker // Remove trailing comma if it is present
292*38e8c45fSAndroid Build Coastguard Worker if (rectDesc[rectDesc.length() - 1] == ',') {
293*38e8c45fSAndroid Build Coastguard Worker rectDesc.erase(rectDesc.length() - 1);
294*38e8c45fSAndroid Build Coastguard Worker }
295*38e8c45fSAndroid Build Coastguard Worker
296*38e8c45fSAndroid Build Coastguard Worker // Parse string description of rectangle
297*38e8c45fSAndroid Build Coastguard Worker Rectangle rect = parseRect(rectDesc);
298*38e8c45fSAndroid Build Coastguard Worker
299*38e8c45fSAndroid Build Coastguard Worker // Add to the list of rectangles
300*38e8c45fSAndroid Build Coastguard Worker rectangle.push_back(rect);
301*38e8c45fSAndroid Build Coastguard Worker
302*38e8c45fSAndroid Build Coastguard Worker // Prepare for description of another rectangle
303*38e8c45fSAndroid Build Coastguard Worker rectDesc = string("");
304*38e8c45fSAndroid Build Coastguard Worker }
305*38e8c45fSAndroid Build Coastguard Worker }
306*38e8c45fSAndroid Build Coastguard Worker
307*38e8c45fSAndroid Build Coastguard Worker // Create list of frames
308*38e8c45fSAndroid Build Coastguard Worker hwc_display_contents_1_t *list;
309*38e8c45fSAndroid Build Coastguard Worker list = hwcTestCreateLayerList(rectangle.size());
310*38e8c45fSAndroid Build Coastguard Worker if (list == NULL) {
311*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestCreateLayerList failed");
312*38e8c45fSAndroid Build Coastguard Worker exit(5);
313*38e8c45fSAndroid Build Coastguard Worker }
314*38e8c45fSAndroid Build Coastguard Worker
315*38e8c45fSAndroid Build Coastguard Worker hwc_layer_1_t *layer = &list->hwLayers[0];
316*38e8c45fSAndroid Build Coastguard Worker for (std::list<Rectangle>::iterator it = rectangle.begin();
317*38e8c45fSAndroid Build Coastguard Worker it != rectangle.end(); ++it, ++layer) {
318*38e8c45fSAndroid Build Coastguard Worker layer->handle = it->texture->handle;
319*38e8c45fSAndroid Build Coastguard Worker layer->blending = it->blend;
320*38e8c45fSAndroid Build Coastguard Worker layer->transform = it->transform;
321*38e8c45fSAndroid Build Coastguard Worker layer->sourceCrop = it->sourceCrop;
322*38e8c45fSAndroid Build Coastguard Worker layer->displayFrame = it->displayFrame;
323*38e8c45fSAndroid Build Coastguard Worker
324*38e8c45fSAndroid Build Coastguard Worker layer->visibleRegionScreen.numRects = 1;
325*38e8c45fSAndroid Build Coastguard Worker layer->visibleRegionScreen.rects = &layer->displayFrame;
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker
328*38e8c45fSAndroid Build Coastguard Worker // Perform prepare operation
329*38e8c45fSAndroid Build Coastguard Worker if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); }
330*38e8c45fSAndroid Build Coastguard Worker hwcDevice->prepare(hwcDevice, 1, &list);
331*38e8c45fSAndroid Build Coastguard Worker if (verbose) {
332*38e8c45fSAndroid Build Coastguard Worker testPrintI("Post Prepare:");
333*38e8c45fSAndroid Build Coastguard Worker hwcTestDisplayListPrepareModifiable(list);
334*38e8c45fSAndroid Build Coastguard Worker }
335*38e8c45fSAndroid Build Coastguard Worker
336*38e8c45fSAndroid Build Coastguard Worker // Turn off the geometry changed flag
337*38e8c45fSAndroid Build Coastguard Worker list->flags &= ~HWC_GEOMETRY_CHANGED;
338*38e8c45fSAndroid Build Coastguard Worker
339*38e8c45fSAndroid Build Coastguard Worker // Perform the set operation(s)
340*38e8c45fSAndroid Build Coastguard Worker if (verbose) {testPrintI("Set:"); }
341*38e8c45fSAndroid Build Coastguard Worker if (verbose) { hwcTestDisplayListHandles(list); }
342*38e8c45fSAndroid Build Coastguard Worker list->dpy = dpy;
343*38e8c45fSAndroid Build Coastguard Worker list->sur = surface;
344*38e8c45fSAndroid Build Coastguard Worker hwcDevice->set(hwcDevice, 1, &list);
345*38e8c45fSAndroid Build Coastguard Worker
346*38e8c45fSAndroid Build Coastguard Worker testDelay(endDelay);
347*38e8c45fSAndroid Build Coastguard Worker
348*38e8c45fSAndroid Build Coastguard Worker // Start framework
349*38e8c45fSAndroid Build Coastguard Worker rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
350*38e8c45fSAndroid Build Coastguard Worker if (rv >= (signed) sizeof(cmd) - 1) {
351*38e8c45fSAndroid Build Coastguard Worker testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
352*38e8c45fSAndroid Build Coastguard Worker exit(6);
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker testExecCmd(cmd);
355*38e8c45fSAndroid Build Coastguard Worker
356*38e8c45fSAndroid Build Coastguard Worker return 0;
357*38e8c45fSAndroid Build Coastguard Worker }
358*38e8c45fSAndroid Build Coastguard Worker
359*38e8c45fSAndroid Build Coastguard Worker // Parse string description of rectangle and add it to list of rectangles
360*38e8c45fSAndroid Build Coastguard Worker // to be rendered.
parseRect(const string & rectStr)361*38e8c45fSAndroid Build Coastguard Worker static Rectangle parseRect(const string& rectStr)
362*38e8c45fSAndroid Build Coastguard Worker {
363*38e8c45fSAndroid Build Coastguard Worker int rv;
364*38e8c45fSAndroid Build Coastguard Worker string str;
365*38e8c45fSAndroid Build Coastguard Worker bool error;
366*38e8c45fSAndroid Build Coastguard Worker istringstream in(rectStr);
367*38e8c45fSAndroid Build Coastguard Worker const struct hwcTestGraphicFormat *format;
368*38e8c45fSAndroid Build Coastguard Worker Rectangle rect;
369*38e8c45fSAndroid Build Coastguard Worker
370*38e8c45fSAndroid Build Coastguard Worker // Graphic Format
371*38e8c45fSAndroid Build Coastguard Worker in >> str;
372*38e8c45fSAndroid Build Coastguard Worker if (!in) {
373*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error parsing format from: %s", rectStr.c_str());
374*38e8c45fSAndroid Build Coastguard Worker exit(20);
375*38e8c45fSAndroid Build Coastguard Worker }
376*38e8c45fSAndroid Build Coastguard Worker format = hwcTestGraphicFormatLookup(str.c_str());
377*38e8c45fSAndroid Build Coastguard Worker if (format == NULL) {
378*38e8c45fSAndroid Build Coastguard Worker testPrintE("Unknown graphic format in: %s", rectStr.c_str());
379*38e8c45fSAndroid Build Coastguard Worker exit(21);
380*38e8c45fSAndroid Build Coastguard Worker }
381*38e8c45fSAndroid Build Coastguard Worker rect.format = format->format;
382*38e8c45fSAndroid Build Coastguard Worker
383*38e8c45fSAndroid Build Coastguard Worker // Display Frame
384*38e8c45fSAndroid Build Coastguard Worker rect.displayFrame = hwcTestParseHwcRect(in, error);
385*38e8c45fSAndroid Build Coastguard Worker if (error) {
386*38e8c45fSAndroid Build Coastguard Worker testPrintE("Invalid display frame in: %s", rectStr.c_str());
387*38e8c45fSAndroid Build Coastguard Worker exit(22);
388*38e8c45fSAndroid Build Coastguard Worker }
389*38e8c45fSAndroid Build Coastguard Worker
390*38e8c45fSAndroid Build Coastguard Worker // Set default sourceDim and sourceCrop based on size of display frame.
391*38e8c45fSAndroid Build Coastguard Worker // Default is source size equal to the size of the display frame, with
392*38e8c45fSAndroid Build Coastguard Worker // the source crop being the entire size of the source frame.
393*38e8c45fSAndroid Build Coastguard Worker rect.sourceDim = HwcTestDim(rect.displayFrame.right
394*38e8c45fSAndroid Build Coastguard Worker - rect.displayFrame.left,
395*38e8c45fSAndroid Build Coastguard Worker rect.displayFrame.bottom
396*38e8c45fSAndroid Build Coastguard Worker - rect.displayFrame.top);
397*38e8c45fSAndroid Build Coastguard Worker rect.sourceCrop.left = 0;
398*38e8c45fSAndroid Build Coastguard Worker rect.sourceCrop.top = 0;
399*38e8c45fSAndroid Build Coastguard Worker rect.sourceCrop.right = rect.sourceDim.width();
400*38e8c45fSAndroid Build Coastguard Worker rect.sourceCrop.bottom = rect.sourceDim.height();
401*38e8c45fSAndroid Build Coastguard Worker
402*38e8c45fSAndroid Build Coastguard Worker // Optional settings
403*38e8c45fSAndroid Build Coastguard Worker while ((in.tellg() < (streampos) in.str().length())
404*38e8c45fSAndroid Build Coastguard Worker && (in.tellg() != (streampos) -1)) {
405*38e8c45fSAndroid Build Coastguard Worker string attrName;
406*38e8c45fSAndroid Build Coastguard Worker
407*38e8c45fSAndroid Build Coastguard Worker in >> attrName;
408*38e8c45fSAndroid Build Coastguard Worker if (in.eof()) { break; }
409*38e8c45fSAndroid Build Coastguard Worker if (!in) {
410*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error reading attribute name in: %s",
411*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
412*38e8c45fSAndroid Build Coastguard Worker exit(23);
413*38e8c45fSAndroid Build Coastguard Worker }
414*38e8c45fSAndroid Build Coastguard Worker
415*38e8c45fSAndroid Build Coastguard Worker // Transform
416*38e8c45fSAndroid Build Coastguard Worker if (attrName == "transform:") { // Transform
417*38e8c45fSAndroid Build Coastguard Worker string str;
418*38e8c45fSAndroid Build Coastguard Worker
419*38e8c45fSAndroid Build Coastguard Worker in >> str;
420*38e8c45fSAndroid Build Coastguard Worker if (str == "none") {
421*38e8c45fSAndroid Build Coastguard Worker rect.transform = 0;
422*38e8c45fSAndroid Build Coastguard Worker } else if (str == "fliph") {
423*38e8c45fSAndroid Build Coastguard Worker rect.transform = HWC_TRANSFORM_FLIP_H;
424*38e8c45fSAndroid Build Coastguard Worker } else if (str == "flipv") {
425*38e8c45fSAndroid Build Coastguard Worker rect.transform = HWC_TRANSFORM_FLIP_V;
426*38e8c45fSAndroid Build Coastguard Worker } else if (str == "rot90") {
427*38e8c45fSAndroid Build Coastguard Worker rect.transform = HWC_TRANSFORM_ROT_90;
428*38e8c45fSAndroid Build Coastguard Worker } else if (str == "rot180") {
429*38e8c45fSAndroid Build Coastguard Worker rect.transform = HWC_TRANSFORM_ROT_180;
430*38e8c45fSAndroid Build Coastguard Worker } else if (str == "rot270") {
431*38e8c45fSAndroid Build Coastguard Worker rect.transform = HWC_TRANSFORM_ROT_270;
432*38e8c45fSAndroid Build Coastguard Worker } else {
433*38e8c45fSAndroid Build Coastguard Worker testPrintE("Unknown transform of \"%s\" in: %s", str.c_str(),
434*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
435*38e8c45fSAndroid Build Coastguard Worker exit(24);
436*38e8c45fSAndroid Build Coastguard Worker }
437*38e8c45fSAndroid Build Coastguard Worker } else if (attrName == "blend:") { // Blend
438*38e8c45fSAndroid Build Coastguard Worker string str;
439*38e8c45fSAndroid Build Coastguard Worker
440*38e8c45fSAndroid Build Coastguard Worker in >> str;
441*38e8c45fSAndroid Build Coastguard Worker if (str == string("none")) {
442*38e8c45fSAndroid Build Coastguard Worker rect.blend = HWC_BLENDING_NONE;
443*38e8c45fSAndroid Build Coastguard Worker } else if (str == "premult") {
444*38e8c45fSAndroid Build Coastguard Worker rect.blend = HWC_BLENDING_PREMULT;
445*38e8c45fSAndroid Build Coastguard Worker } else if (str == "coverage") {
446*38e8c45fSAndroid Build Coastguard Worker rect.blend = HWC_BLENDING_COVERAGE;
447*38e8c45fSAndroid Build Coastguard Worker } else {
448*38e8c45fSAndroid Build Coastguard Worker testPrintE("Unknown blend of \"%s\" in: %s", str.c_str(),
449*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
450*38e8c45fSAndroid Build Coastguard Worker exit(25);
451*38e8c45fSAndroid Build Coastguard Worker }
452*38e8c45fSAndroid Build Coastguard Worker } else if (attrName == "color:") { // Color
453*38e8c45fSAndroid Build Coastguard Worker rect.color = hwcTestParseColor(in, error);
454*38e8c45fSAndroid Build Coastguard Worker if (error) {
455*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error parsing color in: %s", rectStr.c_str());
456*38e8c45fSAndroid Build Coastguard Worker exit(26);
457*38e8c45fSAndroid Build Coastguard Worker }
458*38e8c45fSAndroid Build Coastguard Worker } else if (attrName == "alpha:") { // Alpha
459*38e8c45fSAndroid Build Coastguard Worker in >> rect.alpha;
460*38e8c45fSAndroid Build Coastguard Worker if (!in) {
461*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error parsing value for alpha attribute in: %s",
462*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
463*38e8c45fSAndroid Build Coastguard Worker exit(27);
464*38e8c45fSAndroid Build Coastguard Worker }
465*38e8c45fSAndroid Build Coastguard Worker } else if (attrName == "sourceDim:") { // Source Dimension
466*38e8c45fSAndroid Build Coastguard Worker rect.sourceDim = hwcTestParseDim(in, error);
467*38e8c45fSAndroid Build Coastguard Worker if (error) {
468*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error parsing source dimenision in: %s",
469*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
470*38e8c45fSAndroid Build Coastguard Worker exit(28);
471*38e8c45fSAndroid Build Coastguard Worker }
472*38e8c45fSAndroid Build Coastguard Worker } else if (attrName == "sourceCrop:") { // Source Crop
473*38e8c45fSAndroid Build Coastguard Worker rect.sourceCrop = hwcTestParseHwcRect(in, error);
474*38e8c45fSAndroid Build Coastguard Worker if (error) {
475*38e8c45fSAndroid Build Coastguard Worker testPrintE("Error parsing source crop in: %s",
476*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
477*38e8c45fSAndroid Build Coastguard Worker exit(29);
478*38e8c45fSAndroid Build Coastguard Worker }
479*38e8c45fSAndroid Build Coastguard Worker } else { // Unknown attribute
480*38e8c45fSAndroid Build Coastguard Worker testPrintE("Unknown attribute of \"%s\" in: %s", attrName.c_str(),
481*38e8c45fSAndroid Build Coastguard Worker rectStr.c_str());
482*38e8c45fSAndroid Build Coastguard Worker exit(30);
483*38e8c45fSAndroid Build Coastguard Worker }
484*38e8c45fSAndroid Build Coastguard Worker }
485*38e8c45fSAndroid Build Coastguard Worker
486*38e8c45fSAndroid Build Coastguard Worker // Validate
487*38e8c45fSAndroid Build Coastguard Worker if (((uint32_t) rect.sourceCrop.left >= rect.sourceDim.width())
488*38e8c45fSAndroid Build Coastguard Worker || ((uint32_t) rect.sourceCrop.right > rect.sourceDim.width())
489*38e8c45fSAndroid Build Coastguard Worker || ((uint32_t) rect.sourceCrop.top >= rect.sourceDim.height())
490*38e8c45fSAndroid Build Coastguard Worker || ((uint32_t) rect.sourceCrop.bottom > rect.sourceDim.height())) {
491*38e8c45fSAndroid Build Coastguard Worker testPrintE("Invalid source crop in: %s", rectStr.c_str());
492*38e8c45fSAndroid Build Coastguard Worker exit(31);
493*38e8c45fSAndroid Build Coastguard Worker }
494*38e8c45fSAndroid Build Coastguard Worker if ((rect.displayFrame.left >= width)
495*38e8c45fSAndroid Build Coastguard Worker || (rect.displayFrame.right > width)
496*38e8c45fSAndroid Build Coastguard Worker || (rect.displayFrame.top >= height)
497*38e8c45fSAndroid Build Coastguard Worker || (rect.displayFrame.bottom > height)) {
498*38e8c45fSAndroid Build Coastguard Worker testPrintE("Invalid display frame in: %s", rectStr.c_str());
499*38e8c45fSAndroid Build Coastguard Worker exit(32);
500*38e8c45fSAndroid Build Coastguard Worker }
501*38e8c45fSAndroid Build Coastguard Worker if ((rect.alpha < 0.0) || (rect.alpha > 1.0)) {
502*38e8c45fSAndroid Build Coastguard Worker testPrintE("Invalid alpha in: %s", rectStr.c_str());
503*38e8c45fSAndroid Build Coastguard Worker exit(33);
504*38e8c45fSAndroid Build Coastguard Worker }
505*38e8c45fSAndroid Build Coastguard Worker
506*38e8c45fSAndroid Build Coastguard Worker // Create source texture
507*38e8c45fSAndroid Build Coastguard Worker rect.texture = new GraphicBuffer(rect.sourceDim.width(),
508*38e8c45fSAndroid Build Coastguard Worker rect.sourceDim.height(),
509*38e8c45fSAndroid Build Coastguard Worker rect.format, texUsage);
510*38e8c45fSAndroid Build Coastguard Worker if ((rv = rect.texture->initCheck()) != NO_ERROR) {
511*38e8c45fSAndroid Build Coastguard Worker testPrintE("source texture initCheck failed, rv: %i", rv);
512*38e8c45fSAndroid Build Coastguard Worker testPrintE(" %s", rectStr.c_str());
513*38e8c45fSAndroid Build Coastguard Worker
514*38e8c45fSAndroid Build Coastguard Worker }
515*38e8c45fSAndroid Build Coastguard Worker
516*38e8c45fSAndroid Build Coastguard Worker // Fill with uniform color
517*38e8c45fSAndroid Build Coastguard Worker hwcTestFillColor(rect.texture.get(), rect.color, rect.alpha);
518*38e8c45fSAndroid Build Coastguard Worker if (verbose) {
519*38e8c45fSAndroid Build Coastguard Worker testPrintI(" buf: %p handle: %p format: %s width: %u height: %u "
520*38e8c45fSAndroid Build Coastguard Worker "color: %s alpha: %f",
521*38e8c45fSAndroid Build Coastguard Worker rect.texture.get(), rect.texture->handle, format->desc,
522*38e8c45fSAndroid Build Coastguard Worker rect.sourceDim.width(), rect.sourceDim.height(),
523*38e8c45fSAndroid Build Coastguard Worker string(rect.color).c_str(), rect.alpha);
524*38e8c45fSAndroid Build Coastguard Worker }
525*38e8c45fSAndroid Build Coastguard Worker
526*38e8c45fSAndroid Build Coastguard Worker return rect;
527*38e8c45fSAndroid Build Coastguard Worker }
528*38e8c45fSAndroid Build Coastguard Worker
init(void)529*38e8c45fSAndroid Build Coastguard Worker void init(void)
530*38e8c45fSAndroid Build Coastguard Worker {
531*38e8c45fSAndroid Build Coastguard Worker // Seed pseudo random number generator
532*38e8c45fSAndroid Build Coastguard Worker // Needed so that the pad areas of frames are filled with a deterministic
533*38e8c45fSAndroid Build Coastguard Worker // pseudo random value.
534*38e8c45fSAndroid Build Coastguard Worker srand48(0);
535*38e8c45fSAndroid Build Coastguard Worker
536*38e8c45fSAndroid Build Coastguard Worker hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);
537*38e8c45fSAndroid Build Coastguard Worker
538*38e8c45fSAndroid Build Coastguard Worker hwcTestOpenHwc(&hwcDevice);
539*38e8c45fSAndroid Build Coastguard Worker }
540*38e8c45fSAndroid Build Coastguard Worker
printSyntax(const char * cmd)541*38e8c45fSAndroid Build Coastguard Worker void printSyntax(const char *cmd)
542*38e8c45fSAndroid Build Coastguard Worker {
543*38e8c45fSAndroid Build Coastguard Worker testPrintE(" %s [options] (graphicFormat displayFrame [attributes],)...",
544*38e8c45fSAndroid Build Coastguard Worker cmd);
545*38e8c45fSAndroid Build Coastguard Worker testPrintE(" options:");
546*38e8c45fSAndroid Build Coastguard Worker testPrintE(" -D End of test delay");
547*38e8c45fSAndroid Build Coastguard Worker testPrintE(" -v Verbose");
548*38e8c45fSAndroid Build Coastguard Worker testPrintE("");
549*38e8c45fSAndroid Build Coastguard Worker testPrintE(" graphic formats:");
550*38e8c45fSAndroid Build Coastguard Worker for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
551*38e8c45fSAndroid Build Coastguard Worker testPrintE(" %s", hwcTestGraphicFormat[n1].desc);
552*38e8c45fSAndroid Build Coastguard Worker }
553*38e8c45fSAndroid Build Coastguard Worker testPrintE("");
554*38e8c45fSAndroid Build Coastguard Worker testPrintE(" displayFrame");
555*38e8c45fSAndroid Build Coastguard Worker testPrintE(" [left, top, right, bottom]");
556*38e8c45fSAndroid Build Coastguard Worker testPrintE("");
557*38e8c45fSAndroid Build Coastguard Worker testPrintE(" attributes:");
558*38e8c45fSAndroid Build Coastguard Worker testPrintE(" transform: none | fliph | flipv | rot90 | rot180 "
559*38e8c45fSAndroid Build Coastguard Worker " | rot270");
560*38e8c45fSAndroid Build Coastguard Worker testPrintE(" blend: none | premult | coverage");
561*38e8c45fSAndroid Build Coastguard Worker testPrintE(" color: [0.##, 0.##, 0.##]");
562*38e8c45fSAndroid Build Coastguard Worker testPrintE(" alpha: 0.##");
563*38e8c45fSAndroid Build Coastguard Worker testPrintE(" sourceDim: [width, height]");
564*38e8c45fSAndroid Build Coastguard Worker testPrintE(" sourceCrop: [left, top, right, bottom]");
565*38e8c45fSAndroid Build Coastguard Worker testPrintE("");
566*38e8c45fSAndroid Build Coastguard Worker testPrintE(" Example:");
567*38e8c45fSAndroid Build Coastguard Worker testPrintE(" # White YV12 rectangle, with overlapping turquoise ");
568*38e8c45fSAndroid Build Coastguard Worker testPrintE(" # RGBA8888 rectangle at 30%% (alpha: 0.7) transparency");
569*38e8c45fSAndroid Build Coastguard Worker testPrintE(" %s -v -D 30.0 \\", cmd);
570*38e8c45fSAndroid Build Coastguard Worker testPrintE(" YV12 [50, 80, 200, 300] transform: none \\");
571*38e8c45fSAndroid Build Coastguard Worker testPrintE(" color: [1.0, 0.5, 0.5], \\");
572*38e8c45fSAndroid Build Coastguard Worker testPrintE(" RGBA8888 [100, 150, 300, 400] blend: coverage \\");
573*38e8c45fSAndroid Build Coastguard Worker testPrintE(" color: [0.251, 0.878, 0.816] alpha: 0.7 \\");
574*38e8c45fSAndroid Build Coastguard Worker testPrintE(" sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]");
575*38e8c45fSAndroid Build Coastguard Worker }
576