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