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