1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker *
4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker *
8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker *
10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker *
16*38e8c45fSAndroid Build Coastguard Worker */
17*38e8c45fSAndroid Build Coastguard Worker
18*38e8c45fSAndroid Build Coastguard Worker /*
19*38e8c45fSAndroid Build Coastguard Worker * Hardware Composer Test Library
20*38e8c45fSAndroid Build Coastguard Worker * Utility library functions for use by the Hardware Composer test cases
21*38e8c45fSAndroid Build Coastguard Worker */
22*38e8c45fSAndroid Build Coastguard Worker
23*38e8c45fSAndroid Build Coastguard Worker #include <arpa/inet.h> // For ntohl() and htonl()
24*38e8c45fSAndroid Build Coastguard Worker
25*38e8c45fSAndroid Build Coastguard Worker #include <cmath>
26*38e8c45fSAndroid Build Coastguard Worker #include <sstream>
27*38e8c45fSAndroid Build Coastguard Worker #include <string>
28*38e8c45fSAndroid Build Coastguard Worker
29*38e8c45fSAndroid Build Coastguard Worker #include "hwcTestLib.h"
30*38e8c45fSAndroid Build Coastguard Worker
31*38e8c45fSAndroid Build Coastguard Worker #include "EGLUtils.h"
32*38e8c45fSAndroid Build Coastguard Worker
33*38e8c45fSAndroid Build Coastguard Worker // Defines
34*38e8c45fSAndroid Build Coastguard Worker #define NUMA(a) (sizeof(a) / sizeof((a)[0]))
35*38e8c45fSAndroid Build Coastguard Worker
36*38e8c45fSAndroid Build Coastguard Worker // Function Prototypes
37*38e8c45fSAndroid Build Coastguard Worker static void printGLString(const char *name, GLenum s);
38*38e8c45fSAndroid Build Coastguard Worker static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
39*38e8c45fSAndroid Build Coastguard Worker static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config);
40*38e8c45fSAndroid Build Coastguard Worker
41*38e8c45fSAndroid Build Coastguard Worker using namespace std;
42*38e8c45fSAndroid Build Coastguard Worker using namespace android;
43*38e8c45fSAndroid Build Coastguard Worker
44*38e8c45fSAndroid Build Coastguard Worker
45*38e8c45fSAndroid Build Coastguard Worker #define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once
46*38e8c45fSAndroid Build Coastguard Worker // it has been added
47*38e8c45fSAndroid Build Coastguard Worker
48*38e8c45fSAndroid Build Coastguard Worker // Initialize Display
hwcTestInitDisplay(bool verbose,EGLDisplay * dpy,EGLSurface * surface,EGLint * width,EGLint * height)49*38e8c45fSAndroid Build Coastguard Worker void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface,
50*38e8c45fSAndroid Build Coastguard Worker EGLint *width, EGLint *height)
51*38e8c45fSAndroid Build Coastguard Worker {
52*38e8c45fSAndroid Build Coastguard Worker static EGLContext context;
53*38e8c45fSAndroid Build Coastguard Worker
54*38e8c45fSAndroid Build Coastguard Worker EGLBoolean returnValue;
55*38e8c45fSAndroid Build Coastguard Worker EGLConfig myConfig = {0};
56*38e8c45fSAndroid Build Coastguard Worker EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
57*38e8c45fSAndroid Build Coastguard Worker EGLint sConfigAttribs[] = {
58*38e8c45fSAndroid Build Coastguard Worker EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
59*38e8c45fSAndroid Build Coastguard Worker EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
60*38e8c45fSAndroid Build Coastguard Worker EGL_NONE };
61*38e8c45fSAndroid Build Coastguard Worker EGLint majorVersion, minorVersion;
62*38e8c45fSAndroid Build Coastguard Worker
63*38e8c45fSAndroid Build Coastguard Worker checkEglError("<init>");
64*38e8c45fSAndroid Build Coastguard Worker *dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
65*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglGetDisplay");
66*38e8c45fSAndroid Build Coastguard Worker if (*dpy == EGL_NO_DISPLAY) {
67*38e8c45fSAndroid Build Coastguard Worker testPrintE("eglGetDisplay returned EGL_NO_DISPLAY");
68*38e8c45fSAndroid Build Coastguard Worker exit(70);
69*38e8c45fSAndroid Build Coastguard Worker }
70*38e8c45fSAndroid Build Coastguard Worker
71*38e8c45fSAndroid Build Coastguard Worker returnValue = eglInitialize(*dpy, &majorVersion, &minorVersion);
72*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglInitialize", returnValue);
73*38e8c45fSAndroid Build Coastguard Worker if (verbose) {
74*38e8c45fSAndroid Build Coastguard Worker testPrintI("EGL version %d.%d", majorVersion, minorVersion);
75*38e8c45fSAndroid Build Coastguard Worker }
76*38e8c45fSAndroid Build Coastguard Worker if (returnValue != EGL_TRUE) {
77*38e8c45fSAndroid Build Coastguard Worker testPrintE("eglInitialize failed");
78*38e8c45fSAndroid Build Coastguard Worker exit(71);
79*38e8c45fSAndroid Build Coastguard Worker }
80*38e8c45fSAndroid Build Coastguard Worker
81*38e8c45fSAndroid Build Coastguard Worker // The tests want to stop the framework and play with the hardware
82*38e8c45fSAndroid Build Coastguard Worker // composer, which means it doesn't make sense to use WindowSurface
83*38e8c45fSAndroid Build Coastguard Worker // here. android_createDisplaySurface() is going away, so just
84*38e8c45fSAndroid Build Coastguard Worker // politely fail here.
85*38e8c45fSAndroid Build Coastguard Worker EGLNativeWindowType window = NULL; //android_createDisplaySurface();
86*38e8c45fSAndroid Build Coastguard Worker if (window == NULL) {
87*38e8c45fSAndroid Build Coastguard Worker testPrintE("android_createDisplaySurface failed");
88*38e8c45fSAndroid Build Coastguard Worker exit(72);
89*38e8c45fSAndroid Build Coastguard Worker }
90*38e8c45fSAndroid Build Coastguard Worker returnValue = EGLUtils::selectConfigForNativeWindow(*dpy,
91*38e8c45fSAndroid Build Coastguard Worker sConfigAttribs, window, &myConfig);
92*38e8c45fSAndroid Build Coastguard Worker if (returnValue) {
93*38e8c45fSAndroid Build Coastguard Worker testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d",
94*38e8c45fSAndroid Build Coastguard Worker returnValue);
95*38e8c45fSAndroid Build Coastguard Worker exit(73);
96*38e8c45fSAndroid Build Coastguard Worker }
97*38e8c45fSAndroid Build Coastguard Worker checkEglError("EGLUtils::selectConfigForNativeWindow");
98*38e8c45fSAndroid Build Coastguard Worker
99*38e8c45fSAndroid Build Coastguard Worker if (verbose) {
100*38e8c45fSAndroid Build Coastguard Worker testPrintI("Chose this configuration:");
101*38e8c45fSAndroid Build Coastguard Worker printEGLConfiguration(*dpy, myConfig);
102*38e8c45fSAndroid Build Coastguard Worker }
103*38e8c45fSAndroid Build Coastguard Worker
104*38e8c45fSAndroid Build Coastguard Worker *surface = eglCreateWindowSurface(*dpy, myConfig, window, NULL);
105*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglCreateWindowSurface");
106*38e8c45fSAndroid Build Coastguard Worker if (*surface == EGL_NO_SURFACE) {
107*38e8c45fSAndroid Build Coastguard Worker testPrintE("gelCreateWindowSurface failed.");
108*38e8c45fSAndroid Build Coastguard Worker exit(74);
109*38e8c45fSAndroid Build Coastguard Worker }
110*38e8c45fSAndroid Build Coastguard Worker
111*38e8c45fSAndroid Build Coastguard Worker context = eglCreateContext(*dpy, myConfig, EGL_NO_CONTEXT, contextAttribs);
112*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglCreateContext");
113*38e8c45fSAndroid Build Coastguard Worker if (context == EGL_NO_CONTEXT) {
114*38e8c45fSAndroid Build Coastguard Worker testPrintE("eglCreateContext failed");
115*38e8c45fSAndroid Build Coastguard Worker exit(75);
116*38e8c45fSAndroid Build Coastguard Worker }
117*38e8c45fSAndroid Build Coastguard Worker returnValue = eglMakeCurrent(*dpy, *surface, *surface, context);
118*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglMakeCurrent", returnValue);
119*38e8c45fSAndroid Build Coastguard Worker if (returnValue != EGL_TRUE) {
120*38e8c45fSAndroid Build Coastguard Worker testPrintE("eglMakeCurrent failed");
121*38e8c45fSAndroid Build Coastguard Worker exit(76);
122*38e8c45fSAndroid Build Coastguard Worker }
123*38e8c45fSAndroid Build Coastguard Worker eglQuerySurface(*dpy, *surface, EGL_WIDTH, width);
124*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglQuerySurface");
125*38e8c45fSAndroid Build Coastguard Worker eglQuerySurface(*dpy, *surface, EGL_HEIGHT, height);
126*38e8c45fSAndroid Build Coastguard Worker checkEglError("eglQuerySurface");
127*38e8c45fSAndroid Build Coastguard Worker
128*38e8c45fSAndroid Build Coastguard Worker if (verbose) {
129*38e8c45fSAndroid Build Coastguard Worker testPrintI("Window dimensions: %d x %d", *width, *height);
130*38e8c45fSAndroid Build Coastguard Worker
131*38e8c45fSAndroid Build Coastguard Worker printGLString("Version", GL_VERSION);
132*38e8c45fSAndroid Build Coastguard Worker printGLString("Vendor", GL_VENDOR);
133*38e8c45fSAndroid Build Coastguard Worker printGLString("Renderer", GL_RENDERER);
134*38e8c45fSAndroid Build Coastguard Worker printGLString("Extensions", GL_EXTENSIONS);
135*38e8c45fSAndroid Build Coastguard Worker }
136*38e8c45fSAndroid Build Coastguard Worker }
137*38e8c45fSAndroid Build Coastguard Worker
138*38e8c45fSAndroid Build Coastguard Worker // Open Hardware Composer Device
hwcTestOpenHwc(hwc_composer_device_1_t ** hwcDevicePtr)139*38e8c45fSAndroid Build Coastguard Worker void hwcTestOpenHwc(hwc_composer_device_1_t **hwcDevicePtr)
140*38e8c45fSAndroid Build Coastguard Worker {
141*38e8c45fSAndroid Build Coastguard Worker int rv;
142*38e8c45fSAndroid Build Coastguard Worker hw_module_t const *hwcModule;
143*38e8c45fSAndroid Build Coastguard Worker
144*38e8c45fSAndroid Build Coastguard Worker if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) {
145*38e8c45fSAndroid Build Coastguard Worker testPrintE("hw_get_module failed, rv: %i", rv);
146*38e8c45fSAndroid Build Coastguard Worker errno = -rv;
147*38e8c45fSAndroid Build Coastguard Worker perror(NULL);
148*38e8c45fSAndroid Build Coastguard Worker exit(77);
149*38e8c45fSAndroid Build Coastguard Worker }
150*38e8c45fSAndroid Build Coastguard Worker if ((rv = hwc_open_1(hwcModule, hwcDevicePtr)) != 0) {
151*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwc_open failed, rv: %i", rv);
152*38e8c45fSAndroid Build Coastguard Worker errno = -rv;
153*38e8c45fSAndroid Build Coastguard Worker perror(NULL);
154*38e8c45fSAndroid Build Coastguard Worker exit(78);
155*38e8c45fSAndroid Build Coastguard Worker }
156*38e8c45fSAndroid Build Coastguard Worker }
157*38e8c45fSAndroid Build Coastguard Worker
158*38e8c45fSAndroid Build Coastguard Worker // Color fraction class to string conversion
operator string()159*38e8c45fSAndroid Build Coastguard Worker ColorFract::operator string()
160*38e8c45fSAndroid Build Coastguard Worker {
161*38e8c45fSAndroid Build Coastguard Worker ostringstream out;
162*38e8c45fSAndroid Build Coastguard Worker
163*38e8c45fSAndroid Build Coastguard Worker out << '[' << this->c1() << ", "
164*38e8c45fSAndroid Build Coastguard Worker << this->c2() << ", "
165*38e8c45fSAndroid Build Coastguard Worker << this->c3() << ']';
166*38e8c45fSAndroid Build Coastguard Worker
167*38e8c45fSAndroid Build Coastguard Worker return out.str();
168*38e8c45fSAndroid Build Coastguard Worker }
169*38e8c45fSAndroid Build Coastguard Worker
170*38e8c45fSAndroid Build Coastguard Worker // Dimension class to string conversion
operator string()171*38e8c45fSAndroid Build Coastguard Worker HwcTestDim::operator string()
172*38e8c45fSAndroid Build Coastguard Worker {
173*38e8c45fSAndroid Build Coastguard Worker ostringstream out;
174*38e8c45fSAndroid Build Coastguard Worker
175*38e8c45fSAndroid Build Coastguard Worker out << '[' << this->width() << ", "
176*38e8c45fSAndroid Build Coastguard Worker << this->height() << ']';
177*38e8c45fSAndroid Build Coastguard Worker
178*38e8c45fSAndroid Build Coastguard Worker return out.str();
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker
181*38e8c45fSAndroid Build Coastguard Worker // Dimension class to hwc_rect conversion
operator hwc_rect() const182*38e8c45fSAndroid Build Coastguard Worker HwcTestDim::operator hwc_rect() const
183*38e8c45fSAndroid Build Coastguard Worker {
184*38e8c45fSAndroid Build Coastguard Worker hwc_rect rect;
185*38e8c45fSAndroid Build Coastguard Worker
186*38e8c45fSAndroid Build Coastguard Worker rect.left = rect.top = 0;
187*38e8c45fSAndroid Build Coastguard Worker
188*38e8c45fSAndroid Build Coastguard Worker rect.right = this->_w;
189*38e8c45fSAndroid Build Coastguard Worker rect.bottom = this->_h;
190*38e8c45fSAndroid Build Coastguard Worker
191*38e8c45fSAndroid Build Coastguard Worker return rect;
192*38e8c45fSAndroid Build Coastguard Worker }
193*38e8c45fSAndroid Build Coastguard Worker
194*38e8c45fSAndroid Build Coastguard Worker // Hardware Composer rectangle to string conversion
hwcTestRect2str(const struct hwc_rect & rect)195*38e8c45fSAndroid Build Coastguard Worker string hwcTestRect2str(const struct hwc_rect& rect)
196*38e8c45fSAndroid Build Coastguard Worker {
197*38e8c45fSAndroid Build Coastguard Worker ostringstream out;
198*38e8c45fSAndroid Build Coastguard Worker
199*38e8c45fSAndroid Build Coastguard Worker out << '[';
200*38e8c45fSAndroid Build Coastguard Worker out << rect.left << ", ";
201*38e8c45fSAndroid Build Coastguard Worker out << rect.top << ", ";
202*38e8c45fSAndroid Build Coastguard Worker out << rect.right << ", ";
203*38e8c45fSAndroid Build Coastguard Worker out << rect.bottom;
204*38e8c45fSAndroid Build Coastguard Worker out << ']';
205*38e8c45fSAndroid Build Coastguard Worker
206*38e8c45fSAndroid Build Coastguard Worker return out.str();
207*38e8c45fSAndroid Build Coastguard Worker }
208*38e8c45fSAndroid Build Coastguard Worker
209*38e8c45fSAndroid Build Coastguard Worker // Parse HWC rectangle description of form [left, top, right, bottom]
hwcTestParseHwcRect(istringstream & in,bool & error)210*38e8c45fSAndroid Build Coastguard Worker struct hwc_rect hwcTestParseHwcRect(istringstream& in, bool& error)
211*38e8c45fSAndroid Build Coastguard Worker {
212*38e8c45fSAndroid Build Coastguard Worker struct hwc_rect rect;
213*38e8c45fSAndroid Build Coastguard Worker char chStart, ch;
214*38e8c45fSAndroid Build Coastguard Worker
215*38e8c45fSAndroid Build Coastguard Worker // Defensively specify that an error occurred. Will clear
216*38e8c45fSAndroid Build Coastguard Worker // error flag if all of parsing succeeds.
217*38e8c45fSAndroid Build Coastguard Worker error = true;
218*38e8c45fSAndroid Build Coastguard Worker
219*38e8c45fSAndroid Build Coastguard Worker // First character should be a [ or <
220*38e8c45fSAndroid Build Coastguard Worker in >> chStart;
221*38e8c45fSAndroid Build Coastguard Worker if (!in || ((chStart != '<') && (chStart != '['))) { return rect; }
222*38e8c45fSAndroid Build Coastguard Worker
223*38e8c45fSAndroid Build Coastguard Worker // Left
224*38e8c45fSAndroid Build Coastguard Worker in >> rect.left;
225*38e8c45fSAndroid Build Coastguard Worker if (!in) { return rect; }
226*38e8c45fSAndroid Build Coastguard Worker in >> ch;
227*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return rect; }
228*38e8c45fSAndroid Build Coastguard Worker
229*38e8c45fSAndroid Build Coastguard Worker // Top
230*38e8c45fSAndroid Build Coastguard Worker in >> rect.top;
231*38e8c45fSAndroid Build Coastguard Worker if (!in) { return rect; }
232*38e8c45fSAndroid Build Coastguard Worker in >> ch;
233*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return rect; }
234*38e8c45fSAndroid Build Coastguard Worker
235*38e8c45fSAndroid Build Coastguard Worker // Right
236*38e8c45fSAndroid Build Coastguard Worker in >> rect.right;
237*38e8c45fSAndroid Build Coastguard Worker if (!in) { return rect; }
238*38e8c45fSAndroid Build Coastguard Worker in >> ch;
239*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return rect; }
240*38e8c45fSAndroid Build Coastguard Worker
241*38e8c45fSAndroid Build Coastguard Worker // Bottom
242*38e8c45fSAndroid Build Coastguard Worker in >> rect.bottom;
243*38e8c45fSAndroid Build Coastguard Worker if (!in) { return rect; }
244*38e8c45fSAndroid Build Coastguard Worker
245*38e8c45fSAndroid Build Coastguard Worker // Closing > or ]
246*38e8c45fSAndroid Build Coastguard Worker in >> ch;
247*38e8c45fSAndroid Build Coastguard Worker if (!in) { return rect; }
248*38e8c45fSAndroid Build Coastguard Worker if (((chStart == '<') && (ch != '>'))
249*38e8c45fSAndroid Build Coastguard Worker || ((chStart == '[') && (ch != ']'))) { return rect; }
250*38e8c45fSAndroid Build Coastguard Worker
251*38e8c45fSAndroid Build Coastguard Worker // Validate right and bottom are greater than left and top
252*38e8c45fSAndroid Build Coastguard Worker if ((rect.right <= rect.left) || (rect.bottom <= rect.top)) { return rect; }
253*38e8c45fSAndroid Build Coastguard Worker
254*38e8c45fSAndroid Build Coastguard Worker // Made It, clear error indicator
255*38e8c45fSAndroid Build Coastguard Worker error = false;
256*38e8c45fSAndroid Build Coastguard Worker
257*38e8c45fSAndroid Build Coastguard Worker return rect;
258*38e8c45fSAndroid Build Coastguard Worker }
259*38e8c45fSAndroid Build Coastguard Worker
260*38e8c45fSAndroid Build Coastguard Worker // Parse dimension of form [width, height]
hwcTestParseDim(istringstream & in,bool & error)261*38e8c45fSAndroid Build Coastguard Worker HwcTestDim hwcTestParseDim(istringstream& in, bool& error)
262*38e8c45fSAndroid Build Coastguard Worker {
263*38e8c45fSAndroid Build Coastguard Worker HwcTestDim dim;
264*38e8c45fSAndroid Build Coastguard Worker char chStart, ch;
265*38e8c45fSAndroid Build Coastguard Worker uint32_t val;
266*38e8c45fSAndroid Build Coastguard Worker
267*38e8c45fSAndroid Build Coastguard Worker // Defensively specify that an error occurred. Will clear
268*38e8c45fSAndroid Build Coastguard Worker // error flag if all of parsing succeeds.
269*38e8c45fSAndroid Build Coastguard Worker error = true;
270*38e8c45fSAndroid Build Coastguard Worker
271*38e8c45fSAndroid Build Coastguard Worker // First character should be a [ or <
272*38e8c45fSAndroid Build Coastguard Worker in >> chStart;
273*38e8c45fSAndroid Build Coastguard Worker if (!in || ((chStart != '<') && (chStart != '['))) { return dim; }
274*38e8c45fSAndroid Build Coastguard Worker
275*38e8c45fSAndroid Build Coastguard Worker // Width
276*38e8c45fSAndroid Build Coastguard Worker in >> val;
277*38e8c45fSAndroid Build Coastguard Worker if (!in) { return dim; }
278*38e8c45fSAndroid Build Coastguard Worker dim.setWidth(val);
279*38e8c45fSAndroid Build Coastguard Worker in >> ch;
280*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return dim; }
281*38e8c45fSAndroid Build Coastguard Worker
282*38e8c45fSAndroid Build Coastguard Worker // Height
283*38e8c45fSAndroid Build Coastguard Worker in >> val;
284*38e8c45fSAndroid Build Coastguard Worker if (!in) { return dim; }
285*38e8c45fSAndroid Build Coastguard Worker dim.setHeight(val);
286*38e8c45fSAndroid Build Coastguard Worker
287*38e8c45fSAndroid Build Coastguard Worker // Closing > or ]
288*38e8c45fSAndroid Build Coastguard Worker in >> ch;
289*38e8c45fSAndroid Build Coastguard Worker if (!in) { return dim; }
290*38e8c45fSAndroid Build Coastguard Worker if (((chStart == '<') && (ch != '>'))
291*38e8c45fSAndroid Build Coastguard Worker || ((chStart == '[') && (ch != ']'))) { return dim; }
292*38e8c45fSAndroid Build Coastguard Worker
293*38e8c45fSAndroid Build Coastguard Worker // Validate width and height greater than 0
294*38e8c45fSAndroid Build Coastguard Worker if ((dim.width() <= 0) || (dim.height() <= 0)) { return dim; }
295*38e8c45fSAndroid Build Coastguard Worker
296*38e8c45fSAndroid Build Coastguard Worker // Made It, clear error indicator
297*38e8c45fSAndroid Build Coastguard Worker error = false;
298*38e8c45fSAndroid Build Coastguard Worker return dim;
299*38e8c45fSAndroid Build Coastguard Worker }
300*38e8c45fSAndroid Build Coastguard Worker
301*38e8c45fSAndroid Build Coastguard Worker // Parse fractional color of form [0.##, 0.##, 0.##]
302*38e8c45fSAndroid Build Coastguard Worker // Fractional values can be from 0.0 to 1.0 inclusive. Note, integer
303*38e8c45fSAndroid Build Coastguard Worker // values of 0.0 and 1.0, which are non-fractional, are considered valid.
304*38e8c45fSAndroid Build Coastguard Worker // They are an exception, all other valid inputs are fractions.
hwcTestParseColor(istringstream & in,bool & error)305*38e8c45fSAndroid Build Coastguard Worker ColorFract hwcTestParseColor(istringstream& in, bool& error)
306*38e8c45fSAndroid Build Coastguard Worker {
307*38e8c45fSAndroid Build Coastguard Worker ColorFract color;
308*38e8c45fSAndroid Build Coastguard Worker char chStart, ch;
309*38e8c45fSAndroid Build Coastguard Worker float c1, c2, c3;
310*38e8c45fSAndroid Build Coastguard Worker
311*38e8c45fSAndroid Build Coastguard Worker // Defensively specify that an error occurred. Will clear
312*38e8c45fSAndroid Build Coastguard Worker // error flag if all of parsing succeeds.
313*38e8c45fSAndroid Build Coastguard Worker error = true;
314*38e8c45fSAndroid Build Coastguard Worker
315*38e8c45fSAndroid Build Coastguard Worker // First character should be a [ or <
316*38e8c45fSAndroid Build Coastguard Worker in >> chStart;
317*38e8c45fSAndroid Build Coastguard Worker if (!in || ((chStart != '<') && (chStart != '['))) { return color; }
318*38e8c45fSAndroid Build Coastguard Worker
319*38e8c45fSAndroid Build Coastguard Worker // 1st Component
320*38e8c45fSAndroid Build Coastguard Worker in >> c1;
321*38e8c45fSAndroid Build Coastguard Worker if (!in) { return color; }
322*38e8c45fSAndroid Build Coastguard Worker if ((c1 < 0.0) || (c1 > 1.0)) { return color; }
323*38e8c45fSAndroid Build Coastguard Worker in >> ch;
324*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return color; }
325*38e8c45fSAndroid Build Coastguard Worker
326*38e8c45fSAndroid Build Coastguard Worker // 2nd Component
327*38e8c45fSAndroid Build Coastguard Worker in >> c2;
328*38e8c45fSAndroid Build Coastguard Worker if (!in) { return color; }
329*38e8c45fSAndroid Build Coastguard Worker if ((c2 < 0.0) || (c2 > 1.0)) { return color; }
330*38e8c45fSAndroid Build Coastguard Worker in >> ch;
331*38e8c45fSAndroid Build Coastguard Worker if (!in || (ch != ',')) { return color; }
332*38e8c45fSAndroid Build Coastguard Worker
333*38e8c45fSAndroid Build Coastguard Worker // 3rd Component
334*38e8c45fSAndroid Build Coastguard Worker in >> c3;
335*38e8c45fSAndroid Build Coastguard Worker if (!in) { return color; }
336*38e8c45fSAndroid Build Coastguard Worker if ((c3 < 0.0) || (c3 > 1.0)) { return color; }
337*38e8c45fSAndroid Build Coastguard Worker
338*38e8c45fSAndroid Build Coastguard Worker // Closing > or ]
339*38e8c45fSAndroid Build Coastguard Worker in >> ch;
340*38e8c45fSAndroid Build Coastguard Worker if (!in) { return color; }
341*38e8c45fSAndroid Build Coastguard Worker if (((chStart == '<') && (ch != '>'))
342*38e8c45fSAndroid Build Coastguard Worker || ((chStart == '[') && (ch != ']'))) { return color; }
343*38e8c45fSAndroid Build Coastguard Worker
344*38e8c45fSAndroid Build Coastguard Worker // Are all the components fractional
345*38e8c45fSAndroid Build Coastguard Worker if ((c1 < 0.0) || (c1 > 1.0)
346*38e8c45fSAndroid Build Coastguard Worker || (c2 < 0.0) || (c2 > 1.0)
347*38e8c45fSAndroid Build Coastguard Worker || (c3 < 0.0) || (c3 > 1.0)) { return color; }
348*38e8c45fSAndroid Build Coastguard Worker
349*38e8c45fSAndroid Build Coastguard Worker // Made It, clear error indicator
350*38e8c45fSAndroid Build Coastguard Worker error = false;
351*38e8c45fSAndroid Build Coastguard Worker
352*38e8c45fSAndroid Build Coastguard Worker return ColorFract(c1, c2, c3);
353*38e8c45fSAndroid Build Coastguard Worker }
354*38e8c45fSAndroid Build Coastguard Worker
355*38e8c45fSAndroid Build Coastguard Worker // Look up and return pointer to structure with the characteristics
356*38e8c45fSAndroid Build Coastguard Worker // of the graphic format named by the desc parameter. Search failure
357*38e8c45fSAndroid Build Coastguard Worker // indicated by the return of NULL.
hwcTestGraphicFormatLookup(const char * desc)358*38e8c45fSAndroid Build Coastguard Worker const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc)
359*38e8c45fSAndroid Build Coastguard Worker {
360*38e8c45fSAndroid Build Coastguard Worker for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
361*38e8c45fSAndroid Build Coastguard Worker if (string(desc) == string(hwcTestGraphicFormat[n1].desc)) {
362*38e8c45fSAndroid Build Coastguard Worker return &hwcTestGraphicFormat[n1];
363*38e8c45fSAndroid Build Coastguard Worker }
364*38e8c45fSAndroid Build Coastguard Worker }
365*38e8c45fSAndroid Build Coastguard Worker
366*38e8c45fSAndroid Build Coastguard Worker return NULL;
367*38e8c45fSAndroid Build Coastguard Worker }
368*38e8c45fSAndroid Build Coastguard Worker
369*38e8c45fSAndroid Build Coastguard Worker // Look up and return pointer to structure with the characteristics
370*38e8c45fSAndroid Build Coastguard Worker // of the graphic format specified by the id parameter. Search failure
371*38e8c45fSAndroid Build Coastguard Worker // indicated by the return of NULL.
hwcTestGraphicFormatLookup(uint32_t id)372*38e8c45fSAndroid Build Coastguard Worker const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id)
373*38e8c45fSAndroid Build Coastguard Worker {
374*38e8c45fSAndroid Build Coastguard Worker for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
375*38e8c45fSAndroid Build Coastguard Worker if (id == hwcTestGraphicFormat[n1].format) {
376*38e8c45fSAndroid Build Coastguard Worker return &hwcTestGraphicFormat[n1];
377*38e8c45fSAndroid Build Coastguard Worker }
378*38e8c45fSAndroid Build Coastguard Worker }
379*38e8c45fSAndroid Build Coastguard Worker
380*38e8c45fSAndroid Build Coastguard Worker return NULL;
381*38e8c45fSAndroid Build Coastguard Worker }
382*38e8c45fSAndroid Build Coastguard Worker
383*38e8c45fSAndroid Build Coastguard Worker
384*38e8c45fSAndroid Build Coastguard Worker // Given the integer ID of a graphic format, return a pointer to
385*38e8c45fSAndroid Build Coastguard Worker // a string that describes the format.
hwcTestGraphicFormat2str(uint32_t format)386*38e8c45fSAndroid Build Coastguard Worker const char *hwcTestGraphicFormat2str(uint32_t format)
387*38e8c45fSAndroid Build Coastguard Worker {
388*38e8c45fSAndroid Build Coastguard Worker const static char *unknown = "unknown";
389*38e8c45fSAndroid Build Coastguard Worker
390*38e8c45fSAndroid Build Coastguard Worker for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
391*38e8c45fSAndroid Build Coastguard Worker if (format == hwcTestGraphicFormat[n1].format) {
392*38e8c45fSAndroid Build Coastguard Worker return hwcTestGraphicFormat[n1].desc;
393*38e8c45fSAndroid Build Coastguard Worker }
394*38e8c45fSAndroid Build Coastguard Worker }
395*38e8c45fSAndroid Build Coastguard Worker
396*38e8c45fSAndroid Build Coastguard Worker return unknown;
397*38e8c45fSAndroid Build Coastguard Worker }
398*38e8c45fSAndroid Build Coastguard Worker
399*38e8c45fSAndroid Build Coastguard Worker /*
400*38e8c45fSAndroid Build Coastguard Worker * hwcTestCreateLayerList
401*38e8c45fSAndroid Build Coastguard Worker * Dynamically creates layer list with numLayers worth
402*38e8c45fSAndroid Build Coastguard Worker * of hwLayers entries.
403*38e8c45fSAndroid Build Coastguard Worker */
hwcTestCreateLayerList(size_t numLayers)404*38e8c45fSAndroid Build Coastguard Worker hwc_display_contents_1_t *hwcTestCreateLayerList(size_t numLayers)
405*38e8c45fSAndroid Build Coastguard Worker {
406*38e8c45fSAndroid Build Coastguard Worker hwc_display_contents_1_t *list;
407*38e8c45fSAndroid Build Coastguard Worker
408*38e8c45fSAndroid Build Coastguard Worker size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t);
409*38e8c45fSAndroid Build Coastguard Worker if ((list = (hwc_display_contents_1_t *) calloc(1, size)) == NULL) {
410*38e8c45fSAndroid Build Coastguard Worker return NULL;
411*38e8c45fSAndroid Build Coastguard Worker }
412*38e8c45fSAndroid Build Coastguard Worker list->flags = HWC_GEOMETRY_CHANGED;
413*38e8c45fSAndroid Build Coastguard Worker list->numHwLayers = numLayers;
414*38e8c45fSAndroid Build Coastguard Worker
415*38e8c45fSAndroid Build Coastguard Worker return list;
416*38e8c45fSAndroid Build Coastguard Worker }
417*38e8c45fSAndroid Build Coastguard Worker
418*38e8c45fSAndroid Build Coastguard Worker /*
419*38e8c45fSAndroid Build Coastguard Worker * hwcTestFreeLayerList
420*38e8c45fSAndroid Build Coastguard Worker * Frees memory previous allocated via hwcTestCreateLayerList().
421*38e8c45fSAndroid Build Coastguard Worker */
hwcTestFreeLayerList(hwc_display_contents_1_t * list)422*38e8c45fSAndroid Build Coastguard Worker void hwcTestFreeLayerList(hwc_display_contents_1_t *list)
423*38e8c45fSAndroid Build Coastguard Worker {
424*38e8c45fSAndroid Build Coastguard Worker free(list);
425*38e8c45fSAndroid Build Coastguard Worker }
426*38e8c45fSAndroid Build Coastguard Worker
427*38e8c45fSAndroid Build Coastguard Worker // Display the settings of the layer list pointed to by list
hwcTestDisplayList(hwc_display_contents_1_t * list)428*38e8c45fSAndroid Build Coastguard Worker void hwcTestDisplayList(hwc_display_contents_1_t *list)
429*38e8c45fSAndroid Build Coastguard Worker {
430*38e8c45fSAndroid Build Coastguard Worker testPrintI(" flags: %#x%s", list->flags,
431*38e8c45fSAndroid Build Coastguard Worker (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : "");
432*38e8c45fSAndroid Build Coastguard Worker testPrintI(" numHwLayers: %u", list->numHwLayers);
433*38e8c45fSAndroid Build Coastguard Worker
434*38e8c45fSAndroid Build Coastguard Worker for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
435*38e8c45fSAndroid Build Coastguard Worker testPrintI(" layer %u compositionType: %#x%s%s", layer,
436*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].compositionType,
437*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
438*38e8c45fSAndroid Build Coastguard Worker ? " FRAMEBUFFER" : "",
439*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].compositionType == HWC_OVERLAY)
440*38e8c45fSAndroid Build Coastguard Worker ? " OVERLAY" : "");
441*38e8c45fSAndroid Build Coastguard Worker
442*38e8c45fSAndroid Build Coastguard Worker testPrintI(" hints: %#x",
443*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].hints,
444*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
445*38e8c45fSAndroid Build Coastguard Worker ? " TRIPLE_BUFFER" : "",
446*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
447*38e8c45fSAndroid Build Coastguard Worker ? " CLEAR_FB" : "");
448*38e8c45fSAndroid Build Coastguard Worker
449*38e8c45fSAndroid Build Coastguard Worker testPrintI(" flags: %#x%s",
450*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].flags,
451*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].flags & HWC_SKIP_LAYER)
452*38e8c45fSAndroid Build Coastguard Worker ? " SKIP_LAYER" : "");
453*38e8c45fSAndroid Build Coastguard Worker
454*38e8c45fSAndroid Build Coastguard Worker testPrintI(" handle: %p",
455*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].handle);
456*38e8c45fSAndroid Build Coastguard Worker
457*38e8c45fSAndroid Build Coastguard Worker // Intentionally skipped display of ROT_180 & ROT_270,
458*38e8c45fSAndroid Build Coastguard Worker // which are formed from combinations of the other flags.
459*38e8c45fSAndroid Build Coastguard Worker testPrintI(" transform: %#x%s%s%s",
460*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].transform,
461*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H)
462*38e8c45fSAndroid Build Coastguard Worker ? " FLIP_H" : "",
463*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V)
464*38e8c45fSAndroid Build Coastguard Worker ? " FLIP_V" : "",
465*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90)
466*38e8c45fSAndroid Build Coastguard Worker ? " ROT_90" : "");
467*38e8c45fSAndroid Build Coastguard Worker
468*38e8c45fSAndroid Build Coastguard Worker testPrintI(" blending: %#x%s%s%s",
469*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].blending,
470*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].blending == HWC_BLENDING_NONE)
471*38e8c45fSAndroid Build Coastguard Worker ? " NONE" : "",
472*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT)
473*38e8c45fSAndroid Build Coastguard Worker ? " PREMULT" : "",
474*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE)
475*38e8c45fSAndroid Build Coastguard Worker ? " COVERAGE" : "");
476*38e8c45fSAndroid Build Coastguard Worker
477*38e8c45fSAndroid Build Coastguard Worker testPrintI(" sourceCrop: %s",
478*38e8c45fSAndroid Build Coastguard Worker hwcTestRect2str(list->hwLayers[layer].sourceCrop).c_str());
479*38e8c45fSAndroid Build Coastguard Worker testPrintI(" displayFrame: %s",
480*38e8c45fSAndroid Build Coastguard Worker hwcTestRect2str(list->hwLayers[layer].displayFrame).c_str());
481*38e8c45fSAndroid Build Coastguard Worker testPrintI(" scaleFactor: [%f, %f]",
482*38e8c45fSAndroid Build Coastguard Worker (float) (list->hwLayers[layer].sourceCrop.right
483*38e8c45fSAndroid Build Coastguard Worker - list->hwLayers[layer].sourceCrop.left)
484*38e8c45fSAndroid Build Coastguard Worker / (float) (list->hwLayers[layer].displayFrame.right
485*38e8c45fSAndroid Build Coastguard Worker - list->hwLayers[layer].displayFrame.left),
486*38e8c45fSAndroid Build Coastguard Worker (float) (list->hwLayers[layer].sourceCrop.bottom
487*38e8c45fSAndroid Build Coastguard Worker - list->hwLayers[layer].sourceCrop.top)
488*38e8c45fSAndroid Build Coastguard Worker / (float) (list->hwLayers[layer].displayFrame.bottom
489*38e8c45fSAndroid Build Coastguard Worker - list->hwLayers[layer].displayFrame.top));
490*38e8c45fSAndroid Build Coastguard Worker }
491*38e8c45fSAndroid Build Coastguard Worker }
492*38e8c45fSAndroid Build Coastguard Worker
493*38e8c45fSAndroid Build Coastguard Worker /*
494*38e8c45fSAndroid Build Coastguard Worker * Display List Prepare Modifiable
495*38e8c45fSAndroid Build Coastguard Worker *
496*38e8c45fSAndroid Build Coastguard Worker * Displays the portions of a list that are meant to be modified by
497*38e8c45fSAndroid Build Coastguard Worker * a prepare call.
498*38e8c45fSAndroid Build Coastguard Worker */
hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t * list)499*38e8c45fSAndroid Build Coastguard Worker void hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t *list)
500*38e8c45fSAndroid Build Coastguard Worker {
501*38e8c45fSAndroid Build Coastguard Worker uint32_t numOverlays = 0;
502*38e8c45fSAndroid Build Coastguard Worker for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
503*38e8c45fSAndroid Build Coastguard Worker if (list->hwLayers[layer].compositionType == HWC_OVERLAY) {
504*38e8c45fSAndroid Build Coastguard Worker numOverlays++;
505*38e8c45fSAndroid Build Coastguard Worker }
506*38e8c45fSAndroid Build Coastguard Worker testPrintI(" layer %u compositionType: %#x%s%s", layer,
507*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].compositionType,
508*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
509*38e8c45fSAndroid Build Coastguard Worker ? " FRAMEBUFFER" : "",
510*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].compositionType == HWC_OVERLAY)
511*38e8c45fSAndroid Build Coastguard Worker ? " OVERLAY" : "");
512*38e8c45fSAndroid Build Coastguard Worker testPrintI(" hints: %#x%s%s",
513*38e8c45fSAndroid Build Coastguard Worker list->hwLayers[layer].hints,
514*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
515*38e8c45fSAndroid Build Coastguard Worker ? " TRIPLE_BUFFER" : "",
516*38e8c45fSAndroid Build Coastguard Worker (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
517*38e8c45fSAndroid Build Coastguard Worker ? " CLEAR_FB" : "");
518*38e8c45fSAndroid Build Coastguard Worker }
519*38e8c45fSAndroid Build Coastguard Worker testPrintI(" numOverlays: %u", numOverlays);
520*38e8c45fSAndroid Build Coastguard Worker }
521*38e8c45fSAndroid Build Coastguard Worker
522*38e8c45fSAndroid Build Coastguard Worker /*
523*38e8c45fSAndroid Build Coastguard Worker * Display List Handles
524*38e8c45fSAndroid Build Coastguard Worker *
525*38e8c45fSAndroid Build Coastguard Worker * Displays the handles of all the graphic buffers in the list.
526*38e8c45fSAndroid Build Coastguard Worker */
hwcTestDisplayListHandles(hwc_display_contents_1_t * list)527*38e8c45fSAndroid Build Coastguard Worker void hwcTestDisplayListHandles(hwc_display_contents_1_t *list)
528*38e8c45fSAndroid Build Coastguard Worker {
529*38e8c45fSAndroid Build Coastguard Worker const unsigned int maxLayersPerLine = 6;
530*38e8c45fSAndroid Build Coastguard Worker
531*38e8c45fSAndroid Build Coastguard Worker ostringstream str(" layers:");
532*38e8c45fSAndroid Build Coastguard Worker for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
533*38e8c45fSAndroid Build Coastguard Worker str << ' ' << list->hwLayers[layer].handle;
534*38e8c45fSAndroid Build Coastguard Worker if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1))
535*38e8c45fSAndroid Build Coastguard Worker && (layer != list->numHwLayers - 1)) {
536*38e8c45fSAndroid Build Coastguard Worker testPrintI("%s", str.str().c_str());
537*38e8c45fSAndroid Build Coastguard Worker str.str(" ");
538*38e8c45fSAndroid Build Coastguard Worker }
539*38e8c45fSAndroid Build Coastguard Worker }
540*38e8c45fSAndroid Build Coastguard Worker testPrintI("%s", str.str().c_str());
541*38e8c45fSAndroid Build Coastguard Worker }
542*38e8c45fSAndroid Build Coastguard Worker
543*38e8c45fSAndroid Build Coastguard Worker // Returns a uint32_t that contains a format specific representation of a
544*38e8c45fSAndroid Build Coastguard Worker // single pixel of the given color and alpha values.
hwcTestColor2Pixel(uint32_t format,ColorFract color,float alpha)545*38e8c45fSAndroid Build Coastguard Worker uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha)
546*38e8c45fSAndroid Build Coastguard Worker {
547*38e8c45fSAndroid Build Coastguard Worker const struct attrib {
548*38e8c45fSAndroid Build Coastguard Worker uint32_t format;
549*38e8c45fSAndroid Build Coastguard Worker bool hostByteOrder;
550*38e8c45fSAndroid Build Coastguard Worker size_t bytes;
551*38e8c45fSAndroid Build Coastguard Worker size_t c1Offset;
552*38e8c45fSAndroid Build Coastguard Worker size_t c1Size;
553*38e8c45fSAndroid Build Coastguard Worker size_t c2Offset;
554*38e8c45fSAndroid Build Coastguard Worker size_t c2Size;
555*38e8c45fSAndroid Build Coastguard Worker size_t c3Offset;
556*38e8c45fSAndroid Build Coastguard Worker size_t c3Size;
557*38e8c45fSAndroid Build Coastguard Worker size_t aOffset;
558*38e8c45fSAndroid Build Coastguard Worker size_t aSize;
559*38e8c45fSAndroid Build Coastguard Worker } attributes[] = {
560*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBA_8888, false, 4, 0, 8, 8, 8, 16, 8, 24, 8},
561*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBX_8888, false, 4, 0, 8, 8, 8, 16, 8, 0, 0},
562*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_888, false, 3, 0, 8, 8, 8, 16, 8, 0, 0},
563*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_565, true, 2, 0, 5, 5, 6, 11, 5, 0, 0},
564*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8, 8, 8, 0, 8, 24, 8},
565*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_YV12, true, 3, 16, 8, 8, 8, 0, 8, 0, 0},
566*38e8c45fSAndroid Build Coastguard Worker };
567*38e8c45fSAndroid Build Coastguard Worker
568*38e8c45fSAndroid Build Coastguard Worker const struct attrib *attrib;
569*38e8c45fSAndroid Build Coastguard Worker for (attrib = attributes; attrib < attributes + NUMA(attributes);
570*38e8c45fSAndroid Build Coastguard Worker attrib++) {
571*38e8c45fSAndroid Build Coastguard Worker if (attrib->format == format) { break; }
572*38e8c45fSAndroid Build Coastguard Worker }
573*38e8c45fSAndroid Build Coastguard Worker if (attrib >= attributes + NUMA(attributes)) {
574*38e8c45fSAndroid Build Coastguard Worker testPrintE("colorFract2Pixel unsupported format of: %u", format);
575*38e8c45fSAndroid Build Coastguard Worker exit(80);
576*38e8c45fSAndroid Build Coastguard Worker }
577*38e8c45fSAndroid Build Coastguard Worker
578*38e8c45fSAndroid Build Coastguard Worker uint32_t pixel;
579*38e8c45fSAndroid Build Coastguard Worker pixel = htonl((uint32_t) round((((1 << attrib->c1Size) - 1) * color.c1()))
580*38e8c45fSAndroid Build Coastguard Worker << ((sizeof(pixel) * BITSPERBYTE)
581*38e8c45fSAndroid Build Coastguard Worker - (attrib->c1Offset + attrib->c1Size)));
582*38e8c45fSAndroid Build Coastguard Worker pixel |= htonl((uint32_t) round((((1 << attrib->c2Size) - 1) * color.c2()))
583*38e8c45fSAndroid Build Coastguard Worker << ((sizeof(pixel) * BITSPERBYTE)
584*38e8c45fSAndroid Build Coastguard Worker - (attrib->c2Offset + attrib->c2Size)));
585*38e8c45fSAndroid Build Coastguard Worker pixel |= htonl((uint32_t) round((((1 << attrib->c3Size) - 1) * color.c3()))
586*38e8c45fSAndroid Build Coastguard Worker << ((sizeof(pixel) * BITSPERBYTE)
587*38e8c45fSAndroid Build Coastguard Worker - (attrib->c3Offset + attrib->c3Size)));
588*38e8c45fSAndroid Build Coastguard Worker if (attrib->aSize) {
589*38e8c45fSAndroid Build Coastguard Worker pixel |= htonl((uint32_t) round((((1 << attrib->aSize) - 1) * alpha))
590*38e8c45fSAndroid Build Coastguard Worker << ((sizeof(pixel) * BITSPERBYTE)
591*38e8c45fSAndroid Build Coastguard Worker - (attrib->aOffset + attrib->aSize)));
592*38e8c45fSAndroid Build Coastguard Worker }
593*38e8c45fSAndroid Build Coastguard Worker if (attrib->hostByteOrder) {
594*38e8c45fSAndroid Build Coastguard Worker pixel = ntohl(pixel);
595*38e8c45fSAndroid Build Coastguard Worker pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE;
596*38e8c45fSAndroid Build Coastguard Worker }
597*38e8c45fSAndroid Build Coastguard Worker
598*38e8c45fSAndroid Build Coastguard Worker return pixel;
599*38e8c45fSAndroid Build Coastguard Worker }
600*38e8c45fSAndroid Build Coastguard Worker
601*38e8c45fSAndroid Build Coastguard Worker // Sets the pixel at the given x and y coordinates to the color and alpha
602*38e8c45fSAndroid Build Coastguard Worker // value given by pixel. The contents of pixel is format specific. It's
603*38e8c45fSAndroid Build Coastguard Worker // value should come from a call to hwcTestColor2Pixel().
hwcTestSetPixel(GraphicBuffer * gBuf,unsigned char * buf,uint32_t x,uint32_t y,uint32_t pixel)604*38e8c45fSAndroid Build Coastguard Worker void hwcTestSetPixel(GraphicBuffer *gBuf, unsigned char *buf,
605*38e8c45fSAndroid Build Coastguard Worker uint32_t x, uint32_t y, uint32_t pixel)
606*38e8c45fSAndroid Build Coastguard Worker {
607*38e8c45fSAndroid Build Coastguard Worker
608*38e8c45fSAndroid Build Coastguard Worker const struct attrib {
609*38e8c45fSAndroid Build Coastguard Worker int format;
610*38e8c45fSAndroid Build Coastguard Worker size_t bytes;
611*38e8c45fSAndroid Build Coastguard Worker } attributes[] = {
612*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBA_8888, 4},
613*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBX_8888, 4},
614*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_888, 3},
615*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_565, 2},
616*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_BGRA_8888, 4},
617*38e8c45fSAndroid Build Coastguard Worker };
618*38e8c45fSAndroid Build Coastguard Worker
619*38e8c45fSAndroid Build Coastguard Worker if (gBuf->getPixelFormat() == HAL_PIXEL_FORMAT_YV12) {
620*38e8c45fSAndroid Build Coastguard Worker uint32_t yPlaneOffset, uPlaneOffset, vPlaneOffset;
621*38e8c45fSAndroid Build Coastguard Worker uint32_t yPlaneStride = gBuf->getStride();
622*38e8c45fSAndroid Build Coastguard Worker uint32_t uPlaneStride = ((gBuf->getStride() / 2) + 0xf) & ~0xf;
623*38e8c45fSAndroid Build Coastguard Worker uint32_t vPlaneStride = uPlaneStride;
624*38e8c45fSAndroid Build Coastguard Worker yPlaneOffset = 0;
625*38e8c45fSAndroid Build Coastguard Worker vPlaneOffset = yPlaneOffset + yPlaneStride * gBuf->getHeight();
626*38e8c45fSAndroid Build Coastguard Worker uPlaneOffset = vPlaneOffset
627*38e8c45fSAndroid Build Coastguard Worker + vPlaneStride * (gBuf->getHeight() / 2);
628*38e8c45fSAndroid Build Coastguard Worker *(buf + yPlaneOffset + y * yPlaneStride + x) = pixel & 0xff;
629*38e8c45fSAndroid Build Coastguard Worker *(buf + uPlaneOffset + (y / 2) * uPlaneStride + (x / 2))
630*38e8c45fSAndroid Build Coastguard Worker = (pixel & 0xff00) >> 8;
631*38e8c45fSAndroid Build Coastguard Worker *(buf + vPlaneOffset + (y / 2) * vPlaneStride + (x / 2))
632*38e8c45fSAndroid Build Coastguard Worker = (pixel & 0xff0000) >> 16;
633*38e8c45fSAndroid Build Coastguard Worker
634*38e8c45fSAndroid Build Coastguard Worker return;
635*38e8c45fSAndroid Build Coastguard Worker }
636*38e8c45fSAndroid Build Coastguard Worker
637*38e8c45fSAndroid Build Coastguard Worker const struct attrib *attrib;
638*38e8c45fSAndroid Build Coastguard Worker for (attrib = attributes; attrib < attributes + NUMA(attributes);
639*38e8c45fSAndroid Build Coastguard Worker attrib++) {
640*38e8c45fSAndroid Build Coastguard Worker if (attrib->format == gBuf->getPixelFormat()) { break; }
641*38e8c45fSAndroid Build Coastguard Worker }
642*38e8c45fSAndroid Build Coastguard Worker if (attrib >= attributes + NUMA(attributes)) {
643*38e8c45fSAndroid Build Coastguard Worker testPrintE("setPixel unsupported format of: %u",
644*38e8c45fSAndroid Build Coastguard Worker gBuf->getPixelFormat());
645*38e8c45fSAndroid Build Coastguard Worker exit(90);
646*38e8c45fSAndroid Build Coastguard Worker }
647*38e8c45fSAndroid Build Coastguard Worker
648*38e8c45fSAndroid Build Coastguard Worker memmove(buf + ((gBuf->getStride() * attrib->bytes) * y)
649*38e8c45fSAndroid Build Coastguard Worker + (attrib->bytes * x), &pixel, attrib->bytes);
650*38e8c45fSAndroid Build Coastguard Worker }
651*38e8c45fSAndroid Build Coastguard Worker
652*38e8c45fSAndroid Build Coastguard Worker // Fill a given graphic buffer with a uniform color and alpha
hwcTestFillColor(GraphicBuffer * gBuf,ColorFract color,float alpha)653*38e8c45fSAndroid Build Coastguard Worker void hwcTestFillColor(GraphicBuffer *gBuf, ColorFract color, float alpha)
654*38e8c45fSAndroid Build Coastguard Worker {
655*38e8c45fSAndroid Build Coastguard Worker unsigned char* buf = NULL;
656*38e8c45fSAndroid Build Coastguard Worker status_t err;
657*38e8c45fSAndroid Build Coastguard Worker uint32_t pixel;
658*38e8c45fSAndroid Build Coastguard Worker
659*38e8c45fSAndroid Build Coastguard Worker pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, alpha);
660*38e8c45fSAndroid Build Coastguard Worker
661*38e8c45fSAndroid Build Coastguard Worker err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
662*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
663*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestFillColor lock failed: %d", err);
664*38e8c45fSAndroid Build Coastguard Worker exit(100);
665*38e8c45fSAndroid Build Coastguard Worker }
666*38e8c45fSAndroid Build Coastguard Worker
667*38e8c45fSAndroid Build Coastguard Worker for (unsigned int x = 0; x < gBuf->getStride(); x++) {
668*38e8c45fSAndroid Build Coastguard Worker for (unsigned int y = 0; y < gBuf->getHeight(); y++) {
669*38e8c45fSAndroid Build Coastguard Worker hwcTestSetPixel(gBuf, buf, x, y, (x < gBuf->getWidth())
670*38e8c45fSAndroid Build Coastguard Worker ? pixel : testRand());
671*38e8c45fSAndroid Build Coastguard Worker }
672*38e8c45fSAndroid Build Coastguard Worker }
673*38e8c45fSAndroid Build Coastguard Worker
674*38e8c45fSAndroid Build Coastguard Worker err = gBuf->unlock();
675*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
676*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestFillColor unlock failed: %d", err);
677*38e8c45fSAndroid Build Coastguard Worker exit(101);
678*38e8c45fSAndroid Build Coastguard Worker }
679*38e8c45fSAndroid Build Coastguard Worker }
680*38e8c45fSAndroid Build Coastguard Worker
681*38e8c45fSAndroid Build Coastguard Worker // Fill the given buffer with a horizontal blend of colors, with the left
682*38e8c45fSAndroid Build Coastguard Worker // side color given by startColor and the right side color given by
683*38e8c45fSAndroid Build Coastguard Worker // endColor. The startColor and endColor values are specified in the format
684*38e8c45fSAndroid Build Coastguard Worker // given by colorFormat, which might be different from the format of the
685*38e8c45fSAndroid Build Coastguard Worker // graphic buffer. When different, a color conversion is done when possible
686*38e8c45fSAndroid Build Coastguard Worker // to the graphic format of the graphic buffer. A color of black is
687*38e8c45fSAndroid Build Coastguard Worker // produced for cases where the conversion is impossible (e.g. out of gamut
688*38e8c45fSAndroid Build Coastguard Worker // values).
hwcTestFillColorHBlend(GraphicBuffer * gBuf,uint32_t colorFormat,ColorFract startColor,ColorFract endColor)689*38e8c45fSAndroid Build Coastguard Worker void hwcTestFillColorHBlend(GraphicBuffer *gBuf, uint32_t colorFormat,
690*38e8c45fSAndroid Build Coastguard Worker ColorFract startColor, ColorFract endColor)
691*38e8c45fSAndroid Build Coastguard Worker {
692*38e8c45fSAndroid Build Coastguard Worker status_t err;
693*38e8c45fSAndroid Build Coastguard Worker unsigned char* buf = NULL;
694*38e8c45fSAndroid Build Coastguard Worker const uint32_t width = gBuf->getWidth();
695*38e8c45fSAndroid Build Coastguard Worker const uint32_t height = gBuf->getHeight();
696*38e8c45fSAndroid Build Coastguard Worker const uint32_t stride = gBuf->getStride();
697*38e8c45fSAndroid Build Coastguard Worker
698*38e8c45fSAndroid Build Coastguard Worker err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
699*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
700*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestFillColorHBlend lock failed: %d", err);
701*38e8c45fSAndroid Build Coastguard Worker exit(110);
702*38e8c45fSAndroid Build Coastguard Worker }
703*38e8c45fSAndroid Build Coastguard Worker
704*38e8c45fSAndroid Build Coastguard Worker for (unsigned int x = 0; x < stride; x++) {
705*38e8c45fSAndroid Build Coastguard Worker uint32_t pixel;
706*38e8c45fSAndroid Build Coastguard Worker if (x < width) {
707*38e8c45fSAndroid Build Coastguard Worker ColorFract color(startColor.c1() + (endColor.c1() - startColor.c1())
708*38e8c45fSAndroid Build Coastguard Worker * ((float) x / (float) (width - 1)),
709*38e8c45fSAndroid Build Coastguard Worker startColor.c2() + (endColor.c2() - startColor.c2())
710*38e8c45fSAndroid Build Coastguard Worker * ((float) x / (float) (width - 1)),
711*38e8c45fSAndroid Build Coastguard Worker startColor.c3() + (endColor.c3() - startColor.c3())
712*38e8c45fSAndroid Build Coastguard Worker * ((float) x / (float) (width - 1)));
713*38e8c45fSAndroid Build Coastguard Worker
714*38e8c45fSAndroid Build Coastguard Worker // When formats differ, convert colors.
715*38e8c45fSAndroid Build Coastguard Worker // Important to not convert when formats are the same, since
716*38e8c45fSAndroid Build Coastguard Worker // out of gamut colors are always converted to black.
717*38e8c45fSAndroid Build Coastguard Worker if (colorFormat != (uint32_t) gBuf->getPixelFormat()) {
718*38e8c45fSAndroid Build Coastguard Worker hwcTestColorConvert(colorFormat, gBuf->getPixelFormat(), color);
719*38e8c45fSAndroid Build Coastguard Worker }
720*38e8c45fSAndroid Build Coastguard Worker pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, 1.0);
721*38e8c45fSAndroid Build Coastguard Worker } else {
722*38e8c45fSAndroid Build Coastguard Worker // Fill pad with random values
723*38e8c45fSAndroid Build Coastguard Worker pixel = testRand();
724*38e8c45fSAndroid Build Coastguard Worker }
725*38e8c45fSAndroid Build Coastguard Worker
726*38e8c45fSAndroid Build Coastguard Worker for (unsigned int y = 0; y < height; y++) {
727*38e8c45fSAndroid Build Coastguard Worker hwcTestSetPixel(gBuf, buf, x, y, pixel);
728*38e8c45fSAndroid Build Coastguard Worker }
729*38e8c45fSAndroid Build Coastguard Worker }
730*38e8c45fSAndroid Build Coastguard Worker
731*38e8c45fSAndroid Build Coastguard Worker err = gBuf->unlock();
732*38e8c45fSAndroid Build Coastguard Worker if (err != 0) {
733*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestFillColorHBlend unlock failed: %d", err);
734*38e8c45fSAndroid Build Coastguard Worker exit(111);
735*38e8c45fSAndroid Build Coastguard Worker }
736*38e8c45fSAndroid Build Coastguard Worker }
737*38e8c45fSAndroid Build Coastguard Worker
738*38e8c45fSAndroid Build Coastguard Worker /*
739*38e8c45fSAndroid Build Coastguard Worker * When possible, converts color specified as a full range value in
740*38e8c45fSAndroid Build Coastguard Worker * the fromFormat, into an equivalent full range color in the toFormat.
741*38e8c45fSAndroid Build Coastguard Worker * When conversion is impossible (e.g. out of gamut color) a color
742*38e8c45fSAndroid Build Coastguard Worker * or black in the full range output format is produced. The input
743*38e8c45fSAndroid Build Coastguard Worker * color is given as a fractional color in the parameter named color.
744*38e8c45fSAndroid Build Coastguard Worker * The produced color is written over the same parameter used to
745*38e8c45fSAndroid Build Coastguard Worker * provide the input color.
746*38e8c45fSAndroid Build Coastguard Worker *
747*38e8c45fSAndroid Build Coastguard Worker * Each graphic format has 3 color components and each of these
748*38e8c45fSAndroid Build Coastguard Worker * components has both a full and in gamut range. This function uses
749*38e8c45fSAndroid Build Coastguard Worker * a table that provides the full and in gamut ranges of each of the
750*38e8c45fSAndroid Build Coastguard Worker * supported graphic formats. The full range is given by members named
751*38e8c45fSAndroid Build Coastguard Worker * c[123]Min to c[123]Max, while the in gamut range is given by members
752*38e8c45fSAndroid Build Coastguard Worker * named c[123]Low to c[123]High. In most cases the full and in gamut
753*38e8c45fSAndroid Build Coastguard Worker * ranges are equivalent. This occurs when the c[123]Min == c[123]Low and
754*38e8c45fSAndroid Build Coastguard Worker * c[123]High == c[123]Max.
755*38e8c45fSAndroid Build Coastguard Worker *
756*38e8c45fSAndroid Build Coastguard Worker * The input and produced colors are both specified as a fractional amount
757*38e8c45fSAndroid Build Coastguard Worker * of the full range. The diagram below provides an overview of the
758*38e8c45fSAndroid Build Coastguard Worker * conversion process. The main steps are:
759*38e8c45fSAndroid Build Coastguard Worker *
760*38e8c45fSAndroid Build Coastguard Worker * 1. Produce black if the input color is out of gamut.
761*38e8c45fSAndroid Build Coastguard Worker *
762*38e8c45fSAndroid Build Coastguard Worker * 2. Convert the in gamut color into the fraction of the fromFromat
763*38e8c45fSAndroid Build Coastguard Worker * in gamut range.
764*38e8c45fSAndroid Build Coastguard Worker *
765*38e8c45fSAndroid Build Coastguard Worker * 3. Convert from the fraction of the in gamut from format range to
766*38e8c45fSAndroid Build Coastguard Worker * the fraction of the in gamut to format range. Produce black
767*38e8c45fSAndroid Build Coastguard Worker * if an equivalent color does not exists.
768*38e8c45fSAndroid Build Coastguard Worker *
769*38e8c45fSAndroid Build Coastguard Worker * 4. Covert from the fraction of the in gamut to format to the
770*38e8c45fSAndroid Build Coastguard Worker * fraction of the full range to format.
771*38e8c45fSAndroid Build Coastguard Worker *
772*38e8c45fSAndroid Build Coastguard Worker * From Format To Format
773*38e8c45fSAndroid Build Coastguard Worker * max high high max
774*38e8c45fSAndroid Build Coastguard Worker * ----+ +-----------+
775*38e8c45fSAndroid Build Coastguard Worker * high \ / \ high
776*38e8c45fSAndroid Build Coastguard Worker * ------\-------------+ +-------->
777*38e8c45fSAndroid Build Coastguard Worker * \
778*38e8c45fSAndroid Build Coastguard Worker * \ +--- black --+
779*38e8c45fSAndroid Build Coastguard Worker * \ / \
780*38e8c45fSAndroid Build Coastguard Worker * \ / +-->
781*38e8c45fSAndroid Build Coastguard Worker * low \ / low
782*38e8c45fSAndroid Build Coastguard Worker * -------- ---+-- black --+
783*38e8c45fSAndroid Build Coastguard Worker * min low low min
784*38e8c45fSAndroid Build Coastguard Worker * ^ ^ ^ ^ ^
785*38e8c45fSAndroid Build Coastguard Worker * | | | | |
786*38e8c45fSAndroid Build Coastguard Worker * | | | | +-- fraction of full range
787*38e8c45fSAndroid Build Coastguard Worker * | | | +-- fraction of valid range
788*38e8c45fSAndroid Build Coastguard Worker * | | +-- fromFormat to toFormat color conversion
789*38e8c45fSAndroid Build Coastguard Worker * | +-- fraction of valid range
790*38e8c45fSAndroid Build Coastguard Worker * +-- fraction of full range
791*38e8c45fSAndroid Build Coastguard Worker */
hwcTestColorConvert(uint32_t fromFormat,uint32_t toFormat,ColorFract & color)792*38e8c45fSAndroid Build Coastguard Worker void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat,
793*38e8c45fSAndroid Build Coastguard Worker ColorFract& color)
794*38e8c45fSAndroid Build Coastguard Worker {
795*38e8c45fSAndroid Build Coastguard Worker const struct attrib {
796*38e8c45fSAndroid Build Coastguard Worker uint32_t format;
797*38e8c45fSAndroid Build Coastguard Worker bool rgb;
798*38e8c45fSAndroid Build Coastguard Worker bool yuv;
799*38e8c45fSAndroid Build Coastguard Worker int c1Min, c1Low, c1High, c1Max;
800*38e8c45fSAndroid Build Coastguard Worker int c2Min, c2Low, c2High, c2Max;
801*38e8c45fSAndroid Build Coastguard Worker int c3Min, c3Low, c3High, c3Max;
802*38e8c45fSAndroid Build Coastguard Worker } attributes[] = {
803*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBA_8888, true, false,
804*38e8c45fSAndroid Build Coastguard Worker 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
805*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGBX_8888, true, false,
806*38e8c45fSAndroid Build Coastguard Worker 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
807*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_888, true, false,
808*38e8c45fSAndroid Build Coastguard Worker 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
809*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_RGB_565, true, false,
810*38e8c45fSAndroid Build Coastguard Worker 0, 0, 31, 31, 0, 0, 63, 63, 0, 0, 31, 31},
811*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_BGRA_8888, true, false,
812*38e8c45fSAndroid Build Coastguard Worker 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
813*38e8c45fSAndroid Build Coastguard Worker {HAL_PIXEL_FORMAT_YV12, false, true,
814*38e8c45fSAndroid Build Coastguard Worker 0, 16, 235, 255, 0, 16, 240, 255, 0, 16, 240, 255},
815*38e8c45fSAndroid Build Coastguard Worker };
816*38e8c45fSAndroid Build Coastguard Worker
817*38e8c45fSAndroid Build Coastguard Worker const struct attrib *fromAttrib;
818*38e8c45fSAndroid Build Coastguard Worker for (fromAttrib = attributes; fromAttrib < attributes + NUMA(attributes);
819*38e8c45fSAndroid Build Coastguard Worker fromAttrib++) {
820*38e8c45fSAndroid Build Coastguard Worker if (fromAttrib->format == fromFormat) { break; }
821*38e8c45fSAndroid Build Coastguard Worker }
822*38e8c45fSAndroid Build Coastguard Worker if (fromAttrib >= attributes + NUMA(attributes)) {
823*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestColorConvert unsupported from format of: %u",
824*38e8c45fSAndroid Build Coastguard Worker fromFormat);
825*38e8c45fSAndroid Build Coastguard Worker exit(120);
826*38e8c45fSAndroid Build Coastguard Worker }
827*38e8c45fSAndroid Build Coastguard Worker
828*38e8c45fSAndroid Build Coastguard Worker const struct attrib *toAttrib;
829*38e8c45fSAndroid Build Coastguard Worker for (toAttrib = attributes; toAttrib < attributes + NUMA(attributes);
830*38e8c45fSAndroid Build Coastguard Worker toAttrib++) {
831*38e8c45fSAndroid Build Coastguard Worker if (toAttrib->format == toFormat) { break; }
832*38e8c45fSAndroid Build Coastguard Worker }
833*38e8c45fSAndroid Build Coastguard Worker if (toAttrib >= attributes + NUMA(attributes)) {
834*38e8c45fSAndroid Build Coastguard Worker testPrintE("hwcTestColorConvert unsupported to format of: %u",
835*38e8c45fSAndroid Build Coastguard Worker toFormat);
836*38e8c45fSAndroid Build Coastguard Worker exit(121);
837*38e8c45fSAndroid Build Coastguard Worker }
838*38e8c45fSAndroid Build Coastguard Worker
839*38e8c45fSAndroid Build Coastguard Worker // Produce black if any of the from components are outside the
840*38e8c45fSAndroid Build Coastguard Worker // valid color range
841*38e8c45fSAndroid Build Coastguard Worker float c1Val = fromAttrib->c1Min
842*38e8c45fSAndroid Build Coastguard Worker + ((float) (fromAttrib->c1Max - fromAttrib->c1Min) * color.c1());
843*38e8c45fSAndroid Build Coastguard Worker float c2Val = fromAttrib->c2Min
844*38e8c45fSAndroid Build Coastguard Worker + ((float) (fromAttrib->c2Max - fromAttrib->c2Min) * color.c2());
845*38e8c45fSAndroid Build Coastguard Worker float c3Val = fromAttrib->c3Min
846*38e8c45fSAndroid Build Coastguard Worker + ((float) (fromAttrib->c3Max - fromAttrib->c3Min) * color.c3());
847*38e8c45fSAndroid Build Coastguard Worker if ((c1Val < fromAttrib->c1Low) || (c1Val > fromAttrib->c1High)
848*38e8c45fSAndroid Build Coastguard Worker || (c2Val < fromAttrib->c2Low) || (c2Val > fromAttrib->c2High)
849*38e8c45fSAndroid Build Coastguard Worker || (c3Val < fromAttrib->c3Low) || (c3Val > fromAttrib->c3High)) {
850*38e8c45fSAndroid Build Coastguard Worker
851*38e8c45fSAndroid Build Coastguard Worker // Return black
852*38e8c45fSAndroid Build Coastguard Worker // Will use representation of black from RGBA8888 graphic format
853*38e8c45fSAndroid Build Coastguard Worker // and recursively convert it to the requested graphic format.
854*38e8c45fSAndroid Build Coastguard Worker color = ColorFract(0.0, 0.0, 0.0);
855*38e8c45fSAndroid Build Coastguard Worker hwcTestColorConvert(HAL_PIXEL_FORMAT_RGBA_8888, toFormat, color);
856*38e8c45fSAndroid Build Coastguard Worker return;
857*38e8c45fSAndroid Build Coastguard Worker }
858*38e8c45fSAndroid Build Coastguard Worker
859*38e8c45fSAndroid Build Coastguard Worker // Within from format, convert from fraction of full range
860*38e8c45fSAndroid Build Coastguard Worker // to fraction of valid range
861*38e8c45fSAndroid Build Coastguard Worker color = ColorFract((c1Val - fromAttrib->c1Low)
862*38e8c45fSAndroid Build Coastguard Worker / (fromAttrib->c1High - fromAttrib->c1Low),
863*38e8c45fSAndroid Build Coastguard Worker (c2Val - fromAttrib->c2Low)
864*38e8c45fSAndroid Build Coastguard Worker / (fromAttrib->c2High - fromAttrib->c2Low),
865*38e8c45fSAndroid Build Coastguard Worker (c3Val - fromAttrib->c3Low)
866*38e8c45fSAndroid Build Coastguard Worker / (fromAttrib->c3High - fromAttrib->c3Low));
867*38e8c45fSAndroid Build Coastguard Worker
868*38e8c45fSAndroid Build Coastguard Worker // If needed perform RGB to YUV conversion
869*38e8c45fSAndroid Build Coastguard Worker float wr = 0.2126, wg = 0.7152, wb = 0.0722; // ITU709 recommended constants
870*38e8c45fSAndroid Build Coastguard Worker if (fromAttrib->rgb && toAttrib->yuv) {
871*38e8c45fSAndroid Build Coastguard Worker float r = color.c1(), g = color.c2(), b = color.c3();
872*38e8c45fSAndroid Build Coastguard Worker float y = wr * r + wg * g + wb * b;
873*38e8c45fSAndroid Build Coastguard Worker float u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5;
874*38e8c45fSAndroid Build Coastguard Worker float v = 0.5 * ((r - y) / (1.0 - wr)) + 0.5;
875*38e8c45fSAndroid Build Coastguard Worker
876*38e8c45fSAndroid Build Coastguard Worker // Produce black if color is outside the YUV gamut
877*38e8c45fSAndroid Build Coastguard Worker if ((y < 0.0) || (y > 1.0)
878*38e8c45fSAndroid Build Coastguard Worker || (u < 0.0) || (u > 1.0)
879*38e8c45fSAndroid Build Coastguard Worker || (v < 0.0) || (v > 1.0)) {
880*38e8c45fSAndroid Build Coastguard Worker y = 0.0;
881*38e8c45fSAndroid Build Coastguard Worker u = v = 0.5;
882*38e8c45fSAndroid Build Coastguard Worker }
883*38e8c45fSAndroid Build Coastguard Worker
884*38e8c45fSAndroid Build Coastguard Worker color = ColorFract(y, u, v);
885*38e8c45fSAndroid Build Coastguard Worker }
886*38e8c45fSAndroid Build Coastguard Worker
887*38e8c45fSAndroid Build Coastguard Worker // If needed perform YUV to RGB conversion
888*38e8c45fSAndroid Build Coastguard Worker // Equations determined from the ITU709 equations for RGB to YUV
889*38e8c45fSAndroid Build Coastguard Worker // conversion, plus the following algebra:
890*38e8c45fSAndroid Build Coastguard Worker //
891*38e8c45fSAndroid Build Coastguard Worker // u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5
892*38e8c45fSAndroid Build Coastguard Worker // 0.5 * ((b - y) / (1.0 - wb)) = u - 0.5
893*38e8c45fSAndroid Build Coastguard Worker // (b - y) / (1.0 - wb) = 2 * (u - 0.5)
894*38e8c45fSAndroid Build Coastguard Worker // b - y = 2 * (u - 0.5) * (1.0 - wb)
895*38e8c45fSAndroid Build Coastguard Worker // b = 2 * (u - 0.5) * (1.0 - wb) + y
896*38e8c45fSAndroid Build Coastguard Worker //
897*38e8c45fSAndroid Build Coastguard Worker // v = 0.5 * ((r -y) / (1.0 - wr)) + 0.5
898*38e8c45fSAndroid Build Coastguard Worker // 0.5 * ((r - y) / (1.0 - wr)) = v - 0.5
899*38e8c45fSAndroid Build Coastguard Worker // (r - y) / (1.0 - wr) = 2 * (v - 0.5)
900*38e8c45fSAndroid Build Coastguard Worker // r - y = 2 * (v - 0.5) * (1.0 - wr)
901*38e8c45fSAndroid Build Coastguard Worker // r = 2 * (v - 0.5) * (1.0 - wr) + y
902*38e8c45fSAndroid Build Coastguard Worker //
903*38e8c45fSAndroid Build Coastguard Worker // y = wr * r + wg * g + wb * b
904*38e8c45fSAndroid Build Coastguard Worker // wr * r + wg * g + wb * b = y
905*38e8c45fSAndroid Build Coastguard Worker // wg * g = y - wr * r - wb * b
906*38e8c45fSAndroid Build Coastguard Worker // g = (y - wr * r - wb * b) / wg
907*38e8c45fSAndroid Build Coastguard Worker if (fromAttrib->yuv && toAttrib->rgb) {
908*38e8c45fSAndroid Build Coastguard Worker float y = color.c1(), u = color.c2(), v = color.c3();
909*38e8c45fSAndroid Build Coastguard Worker float r = 2.0 * (v - 0.5) * (1.0 - wr) + y;
910*38e8c45fSAndroid Build Coastguard Worker float b = 2.0 * (u - 0.5) * (1.0 - wb) + y;
911*38e8c45fSAndroid Build Coastguard Worker float g = (y - wr * r - wb * b) / wg;
912*38e8c45fSAndroid Build Coastguard Worker
913*38e8c45fSAndroid Build Coastguard Worker // Produce black if color is outside the RGB gamut
914*38e8c45fSAndroid Build Coastguard Worker if ((r < 0.0) || (r > 1.0)
915*38e8c45fSAndroid Build Coastguard Worker || (g < 0.0) || (g > 1.0)
916*38e8c45fSAndroid Build Coastguard Worker || (b < 0.0) || (b > 1.0)) {
917*38e8c45fSAndroid Build Coastguard Worker r = g = b = 0.0;
918*38e8c45fSAndroid Build Coastguard Worker }
919*38e8c45fSAndroid Build Coastguard Worker
920*38e8c45fSAndroid Build Coastguard Worker color = ColorFract(r, g, b);
921*38e8c45fSAndroid Build Coastguard Worker }
922*38e8c45fSAndroid Build Coastguard Worker
923*38e8c45fSAndroid Build Coastguard Worker // Within to format, convert from fraction of valid range
924*38e8c45fSAndroid Build Coastguard Worker // to fraction of full range
925*38e8c45fSAndroid Build Coastguard Worker c1Val = (toAttrib->c1Low
926*38e8c45fSAndroid Build Coastguard Worker + (float) (toAttrib->c1High - toAttrib->c1Low) * color.c1());
927*38e8c45fSAndroid Build Coastguard Worker c2Val = (toAttrib->c1Low
928*38e8c45fSAndroid Build Coastguard Worker + (float) (toAttrib->c2High - toAttrib->c2Low) * color.c2());
929*38e8c45fSAndroid Build Coastguard Worker c3Val = (toAttrib->c1Low
930*38e8c45fSAndroid Build Coastguard Worker + (float) (toAttrib->c3High - toAttrib->c3Low) * color.c3());
931*38e8c45fSAndroid Build Coastguard Worker color = ColorFract((float) (c1Val - toAttrib->c1Min)
932*38e8c45fSAndroid Build Coastguard Worker / (float) (toAttrib->c1Max - toAttrib->c1Min),
933*38e8c45fSAndroid Build Coastguard Worker (float) (c2Val - toAttrib->c2Min)
934*38e8c45fSAndroid Build Coastguard Worker / (float) (toAttrib->c2Max - toAttrib->c2Min),
935*38e8c45fSAndroid Build Coastguard Worker (float) (c3Val - toAttrib->c3Min)
936*38e8c45fSAndroid Build Coastguard Worker / (float) (toAttrib->c3Max - toAttrib->c3Min));
937*38e8c45fSAndroid Build Coastguard Worker }
938*38e8c45fSAndroid Build Coastguard Worker
939*38e8c45fSAndroid Build Coastguard Worker // TODO: Use PrintGLString, CechckGlError, and PrintEGLConfiguration
940*38e8c45fSAndroid Build Coastguard Worker // from libglTest
printGLString(const char * name,GLenum s)941*38e8c45fSAndroid Build Coastguard Worker static void printGLString(const char *name, GLenum s)
942*38e8c45fSAndroid Build Coastguard Worker {
943*38e8c45fSAndroid Build Coastguard Worker const char *v = (const char *) glGetString(s);
944*38e8c45fSAndroid Build Coastguard Worker
945*38e8c45fSAndroid Build Coastguard Worker if (v == NULL) {
946*38e8c45fSAndroid Build Coastguard Worker testPrintI("GL %s unknown", name);
947*38e8c45fSAndroid Build Coastguard Worker } else {
948*38e8c45fSAndroid Build Coastguard Worker testPrintI("GL %s = %s", name, v);
949*38e8c45fSAndroid Build Coastguard Worker }
950*38e8c45fSAndroid Build Coastguard Worker }
951*38e8c45fSAndroid Build Coastguard Worker
checkEglError(const char * op,EGLBoolean returnVal)952*38e8c45fSAndroid Build Coastguard Worker static void checkEglError(const char* op, EGLBoolean returnVal)
953*38e8c45fSAndroid Build Coastguard Worker {
954*38e8c45fSAndroid Build Coastguard Worker if (returnVal != EGL_TRUE) {
955*38e8c45fSAndroid Build Coastguard Worker testPrintE("%s() returned %d", op, returnVal);
956*38e8c45fSAndroid Build Coastguard Worker }
957*38e8c45fSAndroid Build Coastguard Worker
958*38e8c45fSAndroid Build Coastguard Worker for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
959*38e8c45fSAndroid Build Coastguard Worker = eglGetError()) {
960*38e8c45fSAndroid Build Coastguard Worker testPrintE("after %s() eglError %s (0x%x)",
961*38e8c45fSAndroid Build Coastguard Worker op, EGLUtils::strerror(error), error);
962*38e8c45fSAndroid Build Coastguard Worker }
963*38e8c45fSAndroid Build Coastguard Worker }
964*38e8c45fSAndroid Build Coastguard Worker
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)965*38e8c45fSAndroid Build Coastguard Worker static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config)
966*38e8c45fSAndroid Build Coastguard Worker {
967*38e8c45fSAndroid Build Coastguard Worker
968*38e8c45fSAndroid Build Coastguard Worker #define X(VAL) {VAL, #VAL}
969*38e8c45fSAndroid Build Coastguard Worker struct {EGLint attribute; const char* name;} names[] = {
970*38e8c45fSAndroid Build Coastguard Worker X(EGL_BUFFER_SIZE),
971*38e8c45fSAndroid Build Coastguard Worker X(EGL_ALPHA_SIZE),
972*38e8c45fSAndroid Build Coastguard Worker X(EGL_BLUE_SIZE),
973*38e8c45fSAndroid Build Coastguard Worker X(EGL_GREEN_SIZE),
974*38e8c45fSAndroid Build Coastguard Worker X(EGL_RED_SIZE),
975*38e8c45fSAndroid Build Coastguard Worker X(EGL_DEPTH_SIZE),
976*38e8c45fSAndroid Build Coastguard Worker X(EGL_STENCIL_SIZE),
977*38e8c45fSAndroid Build Coastguard Worker X(EGL_CONFIG_CAVEAT),
978*38e8c45fSAndroid Build Coastguard Worker X(EGL_CONFIG_ID),
979*38e8c45fSAndroid Build Coastguard Worker X(EGL_LEVEL),
980*38e8c45fSAndroid Build Coastguard Worker X(EGL_MAX_PBUFFER_HEIGHT),
981*38e8c45fSAndroid Build Coastguard Worker X(EGL_MAX_PBUFFER_PIXELS),
982*38e8c45fSAndroid Build Coastguard Worker X(EGL_MAX_PBUFFER_WIDTH),
983*38e8c45fSAndroid Build Coastguard Worker X(EGL_NATIVE_RENDERABLE),
984*38e8c45fSAndroid Build Coastguard Worker X(EGL_NATIVE_VISUAL_ID),
985*38e8c45fSAndroid Build Coastguard Worker X(EGL_NATIVE_VISUAL_TYPE),
986*38e8c45fSAndroid Build Coastguard Worker X(EGL_SAMPLES),
987*38e8c45fSAndroid Build Coastguard Worker X(EGL_SAMPLE_BUFFERS),
988*38e8c45fSAndroid Build Coastguard Worker X(EGL_SURFACE_TYPE),
989*38e8c45fSAndroid Build Coastguard Worker X(EGL_TRANSPARENT_TYPE),
990*38e8c45fSAndroid Build Coastguard Worker X(EGL_TRANSPARENT_RED_VALUE),
991*38e8c45fSAndroid Build Coastguard Worker X(EGL_TRANSPARENT_GREEN_VALUE),
992*38e8c45fSAndroid Build Coastguard Worker X(EGL_TRANSPARENT_BLUE_VALUE),
993*38e8c45fSAndroid Build Coastguard Worker X(EGL_BIND_TO_TEXTURE_RGB),
994*38e8c45fSAndroid Build Coastguard Worker X(EGL_BIND_TO_TEXTURE_RGBA),
995*38e8c45fSAndroid Build Coastguard Worker X(EGL_MIN_SWAP_INTERVAL),
996*38e8c45fSAndroid Build Coastguard Worker X(EGL_MAX_SWAP_INTERVAL),
997*38e8c45fSAndroid Build Coastguard Worker X(EGL_LUMINANCE_SIZE),
998*38e8c45fSAndroid Build Coastguard Worker X(EGL_ALPHA_MASK_SIZE),
999*38e8c45fSAndroid Build Coastguard Worker X(EGL_COLOR_BUFFER_TYPE),
1000*38e8c45fSAndroid Build Coastguard Worker X(EGL_RENDERABLE_TYPE),
1001*38e8c45fSAndroid Build Coastguard Worker X(EGL_CONFORMANT),
1002*38e8c45fSAndroid Build Coastguard Worker };
1003*38e8c45fSAndroid Build Coastguard Worker #undef X
1004*38e8c45fSAndroid Build Coastguard Worker
1005*38e8c45fSAndroid Build Coastguard Worker for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
1006*38e8c45fSAndroid Build Coastguard Worker EGLint value = -1;
1007*38e8c45fSAndroid Build Coastguard Worker EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute,
1008*38e8c45fSAndroid Build Coastguard Worker &value);
1009*38e8c45fSAndroid Build Coastguard Worker EGLint error = eglGetError();
1010*38e8c45fSAndroid Build Coastguard Worker if (returnVal && error == EGL_SUCCESS) {
1011*38e8c45fSAndroid Build Coastguard Worker testPrintI(" %s: %d (%#x)", names[j].name, value, value);
1012*38e8c45fSAndroid Build Coastguard Worker }
1013*38e8c45fSAndroid Build Coastguard Worker }
1014*38e8c45fSAndroid Build Coastguard Worker testPrintI("");
1015*38e8c45fSAndroid Build Coastguard Worker }
1016