/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

/*
 * Hardware Composer Test Library
 * Utility library functions for use by the Hardware Composer test cases
 */

#include <arpa/inet.h> // For ntohl() and htonl()

#include <cmath>
#include <sstream>
#include <string>

#include "hwcTestLib.h"

#include "EGLUtils.h"

// Defines
#define NUMA(a) (sizeof(a) / sizeof((a)[0]))

// Function Prototypes
static void printGLString(const char *name, GLenum s);
static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE);
static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config);

using namespace std;
using namespace android;


#define BITSPERBYTE            8 // TODO: Obtain from <values.h>, once
                                 // it has been added

// Initialize Display
void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface,
    EGLint *width, EGLint *height)
{
    static EGLContext context;

    EGLBoolean returnValue;
    EGLConfig myConfig = {0};
    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
    EGLint sConfigAttribs[] = {
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
        EGL_NONE };
    EGLint majorVersion, minorVersion;

    checkEglError("<init>");
    *dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    checkEglError("eglGetDisplay");
    if (*dpy == EGL_NO_DISPLAY) {
        testPrintE("eglGetDisplay returned EGL_NO_DISPLAY");
        exit(70);
    }

    returnValue = eglInitialize(*dpy, &majorVersion, &minorVersion);
    checkEglError("eglInitialize", returnValue);
    if (verbose) {
        testPrintI("EGL version %d.%d", majorVersion, minorVersion);
    }
    if (returnValue != EGL_TRUE) {
        testPrintE("eglInitialize failed");
        exit(71);
    }

    // The tests want to stop the framework and play with the hardware
    // composer, which means it doesn't make sense to use WindowSurface
    // here.  android_createDisplaySurface() is going away, so just
    // politely fail here.
    EGLNativeWindowType window = NULL; //android_createDisplaySurface();
    if (window == NULL) {
        testPrintE("android_createDisplaySurface failed");
        exit(72);
    }
    returnValue = EGLUtils::selectConfigForNativeWindow(*dpy,
        sConfigAttribs, window, &myConfig);
    if (returnValue) {
        testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d",
            returnValue);
        exit(73);
    }
    checkEglError("EGLUtils::selectConfigForNativeWindow");

    if (verbose) {
        testPrintI("Chose this configuration:");
        printEGLConfiguration(*dpy, myConfig);
    }

    *surface = eglCreateWindowSurface(*dpy, myConfig, window, NULL);
    checkEglError("eglCreateWindowSurface");
    if (*surface == EGL_NO_SURFACE) {
        testPrintE("gelCreateWindowSurface failed.");
        exit(74);
    }

    context = eglCreateContext(*dpy, myConfig, EGL_NO_CONTEXT, contextAttribs);
    checkEglError("eglCreateContext");
    if (context == EGL_NO_CONTEXT) {
        testPrintE("eglCreateContext failed");
        exit(75);
    }
    returnValue = eglMakeCurrent(*dpy, *surface, *surface, context);
    checkEglError("eglMakeCurrent", returnValue);
    if (returnValue != EGL_TRUE) {
        testPrintE("eglMakeCurrent failed");
        exit(76);
    }
    eglQuerySurface(*dpy, *surface, EGL_WIDTH, width);
    checkEglError("eglQuerySurface");
    eglQuerySurface(*dpy, *surface, EGL_HEIGHT, height);
    checkEglError("eglQuerySurface");

    if (verbose) {
        testPrintI("Window dimensions: %d x %d", *width, *height);

        printGLString("Version", GL_VERSION);
        printGLString("Vendor", GL_VENDOR);
        printGLString("Renderer", GL_RENDERER);
        printGLString("Extensions", GL_EXTENSIONS);
    }
}

// Open Hardware Composer Device
void hwcTestOpenHwc(hwc_composer_device_1_t **hwcDevicePtr)
{
    int rv;
    hw_module_t const *hwcModule;

    if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) {
        testPrintE("hw_get_module failed, rv: %i", rv);
        errno = -rv;
        perror(NULL);
        exit(77);
    }
    if ((rv = hwc_open_1(hwcModule, hwcDevicePtr)) != 0) {
        testPrintE("hwc_open failed, rv: %i", rv);
        errno = -rv;
        perror(NULL);
        exit(78);
    }
}

// Color fraction class to string conversion
ColorFract::operator string()
{
    ostringstream out;

    out << '[' << this->c1() << ", "
        << this->c2() << ", "
        << this->c3() << ']';

    return out.str();
}

// Dimension class to string conversion
HwcTestDim::operator string()
{
    ostringstream out;

    out << '[' << this->width() << ", "
        << this->height() << ']';

    return out.str();
}

// Dimension class to hwc_rect conversion
HwcTestDim::operator hwc_rect() const
{
    hwc_rect rect;

    rect.left = rect.top = 0;

    rect.right = this->_w;
    rect.bottom = this->_h;

    return rect;
}

// Hardware Composer rectangle to string conversion
string hwcTestRect2str(const struct hwc_rect& rect)
{
    ostringstream out;

    out << '[';
    out << rect.left << ", ";
    out << rect.top << ", ";
    out << rect.right << ", ";
    out << rect.bottom;
    out << ']';

    return out.str();
}

// Parse HWC rectangle description of form [left, top, right, bottom]
struct hwc_rect hwcTestParseHwcRect(istringstream& in, bool& error)
{
    struct hwc_rect rect;
    char chStart, ch;

    // Defensively specify that an error occurred.  Will clear
    // error flag if all of parsing succeeds.
    error = true;

    // First character should be a [ or <
    in >> chStart;
    if (!in || ((chStart != '<') && (chStart != '['))) { return rect; }

    // Left
    in >> rect.left;
    if (!in) { return rect; }
    in >> ch;
    if (!in || (ch != ',')) { return rect; }

    // Top
    in >> rect.top;
    if (!in) { return rect; }
    in >> ch;
    if (!in || (ch != ',')) { return rect; }

    // Right
    in >> rect.right;
    if (!in) { return rect; }
    in >> ch;
    if (!in || (ch != ',')) { return rect; }

    // Bottom
    in >> rect.bottom;
    if (!in) { return rect; }

    // Closing > or ]
    in >> ch;
    if (!in) { return rect; }
    if (((chStart == '<') && (ch != '>'))
        || ((chStart == '[') && (ch != ']'))) { return rect; }

    // Validate right and bottom are greater than left and top
    if ((rect.right <= rect.left) || (rect.bottom <= rect.top)) { return rect; }

    // Made It, clear error indicator
    error = false;

    return rect;
}

// Parse dimension of form [width, height]
HwcTestDim hwcTestParseDim(istringstream& in, bool& error)
{
    HwcTestDim dim;
    char chStart, ch;
    uint32_t val;

    // Defensively specify that an error occurred.  Will clear
    // error flag if all of parsing succeeds.
    error = true;

    // First character should be a [ or <
    in >> chStart;
    if (!in || ((chStart != '<') && (chStart != '['))) { return dim; }

    // Width
    in >> val;
    if (!in) { return dim; }
    dim.setWidth(val);
    in >> ch;
    if (!in || (ch != ',')) { return dim; }

    // Height
    in >> val;
    if (!in) { return dim; }
    dim.setHeight(val);

    // Closing > or ]
    in >> ch;
    if (!in) { return dim; }
    if (((chStart == '<') && (ch != '>'))
        || ((chStart == '[') && (ch != ']'))) { return dim; }

    // Validate width and height greater than 0
    if ((dim.width() <= 0) || (dim.height() <= 0)) { return dim; }

    // Made It, clear error indicator
    error = false;
    return dim;
}

// Parse fractional color of form [0.##, 0.##, 0.##]
// Fractional values can be from 0.0 to 1.0 inclusive.  Note, integer
// values of 0.0 and 1.0, which are non-fractional, are considered valid.
// They are an exception, all other valid inputs are fractions.
ColorFract hwcTestParseColor(istringstream& in, bool& error)
{
    ColorFract color;
    char chStart, ch;
    float c1, c2, c3;

    // Defensively specify that an error occurred.  Will clear
    // error flag if all of parsing succeeds.
    error = true;

    // First character should be a [ or <
    in >> chStart;
    if (!in || ((chStart != '<') && (chStart != '['))) { return color; }

    // 1st Component
    in >> c1;
    if (!in) { return color; }
    if ((c1 < 0.0) || (c1 > 1.0)) { return color; }
    in >> ch;
    if (!in || (ch != ',')) { return color; }

    // 2nd Component
    in >> c2;
    if (!in) { return color; }
    if ((c2 < 0.0) || (c2 > 1.0)) { return color; }
    in >> ch;
    if (!in || (ch != ',')) { return color; }

    // 3rd Component
    in >> c3;
    if (!in) { return color; }
    if ((c3 < 0.0) || (c3 > 1.0)) { return color; }

    // Closing > or ]
    in >> ch;
    if (!in) { return color; }
    if (((chStart == '<') && (ch != '>'))
        || ((chStart == '[') && (ch != ']'))) { return color; }

    // Are all the components fractional
    if ((c1 < 0.0) || (c1 > 1.0)
        || (c2 < 0.0) || (c2 > 1.0)
        || (c3 < 0.0) || (c3 > 1.0)) { return color; }

    // Made It, clear error indicator
    error = false;

    return ColorFract(c1, c2, c3);
}

// Look up and return pointer to structure with the characteristics
// of the graphic format named by the desc parameter.  Search failure
// indicated by the return of NULL.
const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc)
{
    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
        if (string(desc) == string(hwcTestGraphicFormat[n1].desc)) {
            return &hwcTestGraphicFormat[n1];
        }
    }

    return NULL;
}

// Look up and return pointer to structure with the characteristics
// of the graphic format specified by the id parameter.  Search failure
// indicated by the return of NULL.
const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id)
{
    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
        if (id == hwcTestGraphicFormat[n1].format) {
            return &hwcTestGraphicFormat[n1];
        }
    }

    return NULL;
}


// Given the integer ID of a graphic format, return a pointer to
// a string that describes the format.
const char *hwcTestGraphicFormat2str(uint32_t format)
{
    const static char *unknown = "unknown";

    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
        if (format == hwcTestGraphicFormat[n1].format) {
            return hwcTestGraphicFormat[n1].desc;
        }
    }

    return unknown;
}

/*
 * hwcTestCreateLayerList
 * Dynamically creates layer list with numLayers worth
 * of hwLayers entries.
 */
hwc_display_contents_1_t *hwcTestCreateLayerList(size_t numLayers)
{
    hwc_display_contents_1_t *list;

    size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t);
    if ((list = (hwc_display_contents_1_t *) calloc(1, size)) == NULL) {
        return NULL;
    }
    list->flags = HWC_GEOMETRY_CHANGED;
    list->numHwLayers = numLayers;

    return list;
}

/*
 * hwcTestFreeLayerList
 * Frees memory previous allocated via hwcTestCreateLayerList().
 */
void hwcTestFreeLayerList(hwc_display_contents_1_t *list)
{
    free(list);
}

// Display the settings of the layer list pointed to by list
void hwcTestDisplayList(hwc_display_contents_1_t *list)
{
    testPrintI("  flags: %#x%s", list->flags,
               (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : "");
    testPrintI("  numHwLayers: %u", list->numHwLayers);

    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
        testPrintI("    layer %u compositionType: %#x%s%s", layer,
                   list->hwLayers[layer].compositionType,
                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
                       ? " FRAMEBUFFER" : "",
                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
                       ? " OVERLAY" : "");

        testPrintI("      hints: %#x",
                   list->hwLayers[layer].hints,
                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
                       ? " TRIPLE_BUFFER" : "",
                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
                       ? " CLEAR_FB" : "");

        testPrintI("      flags: %#x%s",
                   list->hwLayers[layer].flags,
                   (list->hwLayers[layer].flags & HWC_SKIP_LAYER)
                       ? " SKIP_LAYER" : "");

        testPrintI("      handle: %p",
                   list->hwLayers[layer].handle);

        // Intentionally skipped display of ROT_180 & ROT_270,
        // which are formed from combinations of the other flags.
        testPrintI("      transform: %#x%s%s%s",
                   list->hwLayers[layer].transform,
                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H)
                       ? " FLIP_H" : "",
                   (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V)
                       ? " FLIP_V" : "",
                   (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90)
                       ? " ROT_90" : "");

        testPrintI("      blending: %#x%s%s%s",
                   list->hwLayers[layer].blending,
                   (list->hwLayers[layer].blending == HWC_BLENDING_NONE)
                       ? " NONE" : "",
                   (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT)
                       ? " PREMULT" : "",
                   (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE)
                       ? " COVERAGE" : "");

        testPrintI("      sourceCrop: %s",
                   hwcTestRect2str(list->hwLayers[layer].sourceCrop).c_str());
        testPrintI("      displayFrame: %s",
                   hwcTestRect2str(list->hwLayers[layer].displayFrame).c_str());
        testPrintI("      scaleFactor: [%f, %f]",
                   (float) (list->hwLayers[layer].sourceCrop.right
                            - list->hwLayers[layer].sourceCrop.left)
                       / (float) (list->hwLayers[layer].displayFrame.right
                            - list->hwLayers[layer].displayFrame.left),
                   (float) (list->hwLayers[layer].sourceCrop.bottom
                            - list->hwLayers[layer].sourceCrop.top)
                       / (float) (list->hwLayers[layer].displayFrame.bottom
                            - list->hwLayers[layer].displayFrame.top));
    }
}

/*
 * Display List Prepare Modifiable
 *
 * Displays the portions of a list that are meant to be modified by
 * a prepare call.
 */
void hwcTestDisplayListPrepareModifiable(hwc_display_contents_1_t *list)
{
    uint32_t numOverlays = 0;
    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
        if (list->hwLayers[layer].compositionType == HWC_OVERLAY) {
            numOverlays++;
        }
        testPrintI("    layer %u compositionType: %#x%s%s", layer,
                   list->hwLayers[layer].compositionType,
                   (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER)
                       ? " FRAMEBUFFER" : "",
                   (list->hwLayers[layer].compositionType == HWC_OVERLAY)
                       ? " OVERLAY" : "");
        testPrintI("      hints: %#x%s%s",
                   list->hwLayers[layer].hints,
                   (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER)
                       ? " TRIPLE_BUFFER" : "",
                   (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB)
                       ? " CLEAR_FB" : "");
    }
    testPrintI("    numOverlays: %u", numOverlays);
}

/*
 * Display List Handles
 *
 * Displays the handles of all the graphic buffers in the list.
 */
void hwcTestDisplayListHandles(hwc_display_contents_1_t *list)
{
    const unsigned int maxLayersPerLine = 6;

    ostringstream str("  layers:");
    for (unsigned int layer = 0; layer < list->numHwLayers; layer++) {
        str << ' ' << list->hwLayers[layer].handle;
        if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1))
            && (layer != list->numHwLayers - 1)) {
            testPrintI("%s", str.str().c_str());
            str.str("    ");
        }
    }
    testPrintI("%s", str.str().c_str());
}

// Returns a uint32_t that contains a format specific representation of a
// single pixel of the given color and alpha values.
uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha)
{
    const struct attrib {
        uint32_t format;
        bool   hostByteOrder;
        size_t bytes;
        size_t c1Offset;
        size_t c1Size;
        size_t c2Offset;
        size_t c2Size;
        size_t c3Offset;
        size_t c3Size;
        size_t aOffset;
        size_t aSize;
    } attributes[] = {
        {HAL_PIXEL_FORMAT_RGBA_8888, false, 4,  0, 8,  8, 8, 16, 8, 24, 8},
        {HAL_PIXEL_FORMAT_RGBX_8888, false, 4,  0, 8,  8, 8, 16, 8,  0, 0},
        {HAL_PIXEL_FORMAT_RGB_888,   false, 3,  0, 8,  8, 8, 16, 8,  0, 0},
        {HAL_PIXEL_FORMAT_RGB_565,   true,  2,  0, 5,  5, 6, 11, 5,  0, 0},
        {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8,  8, 8,  0, 8, 24, 8},
        {HAL_PIXEL_FORMAT_YV12,      true,  3, 16, 8,  8, 8,  0, 8,  0, 0},  
    };

    const struct attrib *attrib;
    for (attrib = attributes; attrib < attributes + NUMA(attributes);
         attrib++) {
        if (attrib->format == format) { break; }
    }
    if (attrib >= attributes + NUMA(attributes)) {
        testPrintE("colorFract2Pixel unsupported format of: %u", format);
        exit(80);
    }

    uint32_t pixel;
    pixel = htonl((uint32_t) round((((1 << attrib->c1Size) - 1) * color.c1()))
         << ((sizeof(pixel) * BITSPERBYTE)
             - (attrib->c1Offset + attrib->c1Size)));
    pixel |= htonl((uint32_t) round((((1 << attrib->c2Size) - 1) * color.c2()))
         << ((sizeof(pixel) * BITSPERBYTE)
             - (attrib->c2Offset + attrib->c2Size)));
    pixel |= htonl((uint32_t) round((((1 << attrib->c3Size) - 1) * color.c3()))
         << ((sizeof(pixel) * BITSPERBYTE)
             - (attrib->c3Offset + attrib->c3Size)));
    if (attrib->aSize) {
        pixel |= htonl((uint32_t) round((((1 << attrib->aSize) - 1) * alpha))
             << ((sizeof(pixel) * BITSPERBYTE)
                 - (attrib->aOffset + attrib->aSize)));
    }
    if (attrib->hostByteOrder) {
        pixel = ntohl(pixel);
        pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE;
    }

    return pixel;
}

// Sets the pixel at the given x and y coordinates to the color and alpha
// value given by pixel.  The contents of pixel is format specific.  It's
// value should come from a call to hwcTestColor2Pixel().
void hwcTestSetPixel(GraphicBuffer *gBuf, unsigned char *buf,
              uint32_t x, uint32_t y, uint32_t pixel)
{

    const struct attrib {
        int format;
        size_t bytes;
    } attributes[] = {
        {HAL_PIXEL_FORMAT_RGBA_8888,  4},
        {HAL_PIXEL_FORMAT_RGBX_8888,  4},
        {HAL_PIXEL_FORMAT_RGB_888,    3},
        {HAL_PIXEL_FORMAT_RGB_565,    2},
        {HAL_PIXEL_FORMAT_BGRA_8888,  4},
    };

    if (gBuf->getPixelFormat() == HAL_PIXEL_FORMAT_YV12) {
        uint32_t yPlaneOffset, uPlaneOffset, vPlaneOffset;
        uint32_t yPlaneStride = gBuf->getStride();
        uint32_t uPlaneStride = ((gBuf->getStride() / 2) + 0xf) & ~0xf;
        uint32_t vPlaneStride = uPlaneStride;
        yPlaneOffset = 0;
        vPlaneOffset = yPlaneOffset + yPlaneStride * gBuf->getHeight();
        uPlaneOffset = vPlaneOffset
                       + vPlaneStride * (gBuf->getHeight() / 2);
        *(buf + yPlaneOffset + y * yPlaneStride + x) = pixel & 0xff;
        *(buf + uPlaneOffset + (y / 2) * uPlaneStride + (x / 2))
            = (pixel & 0xff00) >> 8;
        *(buf + vPlaneOffset + (y / 2) * vPlaneStride + (x / 2))
            = (pixel & 0xff0000) >> 16;

        return;
    }

    const struct attrib *attrib;
    for (attrib = attributes; attrib < attributes + NUMA(attributes);
         attrib++) {
        if (attrib->format == gBuf->getPixelFormat()) { break; }
    }
    if (attrib >= attributes + NUMA(attributes)) {
        testPrintE("setPixel unsupported format of: %u",
                   gBuf->getPixelFormat());
        exit(90);
    }

    memmove(buf + ((gBuf->getStride() * attrib->bytes) * y)
            + (attrib->bytes * x), &pixel, attrib->bytes);
}

// Fill a given graphic buffer with a uniform color and alpha
void hwcTestFillColor(GraphicBuffer *gBuf, ColorFract color, float alpha)
{
    unsigned char* buf = NULL;
    status_t err;
    uint32_t pixel;

    pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, alpha);

    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
    if (err != 0) {
        testPrintE("hwcTestFillColor lock failed: %d", err);
        exit(100);
    }

    for (unsigned int x = 0; x < gBuf->getStride(); x++) {
        for (unsigned int y = 0; y < gBuf->getHeight(); y++) {
            hwcTestSetPixel(gBuf, buf, x, y, (x < gBuf->getWidth())
                            ? pixel : testRand());
        }
    }

    err = gBuf->unlock();
    if (err != 0) {
        testPrintE("hwcTestFillColor unlock failed: %d", err);
        exit(101);
    }
}

// Fill the given buffer with a horizontal blend of colors, with the left
// side color given by startColor and the right side color given by
// endColor.  The startColor and endColor values are specified in the format
// given by colorFormat, which might be different from the format of the
// graphic buffer.  When different, a color conversion is done when possible
// to the graphic format of the graphic buffer.  A color of black is
// produced for cases where the conversion is impossible (e.g. out of gamut
// values).
void hwcTestFillColorHBlend(GraphicBuffer *gBuf, uint32_t colorFormat,
                            ColorFract startColor, ColorFract endColor)
{
    status_t err;
    unsigned char* buf = NULL;
    const uint32_t width = gBuf->getWidth();
    const uint32_t height = gBuf->getHeight();
    const uint32_t stride = gBuf->getStride();

    err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf));
    if (err != 0) {
        testPrintE("hwcTestFillColorHBlend lock failed: %d", err);
        exit(110);
    }

    for (unsigned int x = 0; x < stride; x++) {
        uint32_t pixel;
        if (x < width) {
            ColorFract color(startColor.c1() + (endColor.c1() - startColor.c1())
                                 * ((float) x / (float) (width - 1)),
                             startColor.c2() + (endColor.c2() - startColor.c2())
                                 * ((float) x / (float) (width - 1)),
                             startColor.c3() + (endColor.c3() - startColor.c3())
                                 * ((float) x / (float) (width - 1)));

            // When formats differ, convert colors.
            // Important to not convert when formats are the same, since
            // out of gamut colors are always converted to black.
            if (colorFormat != (uint32_t) gBuf->getPixelFormat()) {
                hwcTestColorConvert(colorFormat, gBuf->getPixelFormat(), color);
            }
            pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, 1.0);
        } else {
            // Fill pad with random values
            pixel = testRand();
        }

        for (unsigned int y = 0; y < height; y++) {
            hwcTestSetPixel(gBuf, buf, x, y, pixel);
        }
    }

    err = gBuf->unlock();
    if (err != 0) {
        testPrintE("hwcTestFillColorHBlend unlock failed: %d", err);
        exit(111);
    }
}

/*
 * When possible, converts color specified as a full range value in
 * the fromFormat, into an equivalent full range color in the toFormat.
 * When conversion is impossible (e.g. out of gamut color) a color
 * or black in the full range output format is produced.  The input
 * color is given as a fractional color in the parameter named color.
 * The produced color is written over the same parameter used to
 * provide the input color.
 *
 * Each graphic format has 3 color components and each of these
 * components has both a full and in gamut range.  This function uses
 * a table that provides the full and in gamut ranges of each of the
 * supported graphic formats.  The full range is given by members named
 * c[123]Min to c[123]Max, while the in gamut range is given by members
 * named c[123]Low to c[123]High.  In most cases the full and in gamut
 * ranges are equivalent.  This occurs when the c[123]Min == c[123]Low and
 * c[123]High == c[123]Max.
 *
 * The input and produced colors are both specified as a fractional amount
 * of the full range.  The diagram below provides an overview of the
 * conversion process.  The main steps are:
 *
 *   1. Produce black if the input color is out of gamut.
 *
 *   2. Convert the in gamut color into the fraction of the fromFromat
 *      in gamut range.
 *
 *   3. Convert from the fraction of the in gamut from format range to
 *      the fraction of the in gamut to format range.  Produce black
 *      if an equivalent color does not exists.
 *
 *   4. Covert from the fraction of the in gamut to format to the
 *      fraction of the full range to format.
 *
 *       From Format                 To Format
 *    max           high            high        max
 *    ----+                 +-----------+
 *    high \               /             \      high
 *    ------\-------------+               +-------->
 *           \
 *            \                   +--- black --+
 *             \                 /              \
 *              \               /                +-->
 *    low        \             /                  low
 *    -------- ---+-- black --+
 *    min             low           low           min
 *     ^               ^      ^      ^             ^
 *     |               |      |      |             |
 *     |               |      |      |             +-- fraction of full range
 *     |               |      |      +-- fraction of valid range
 *     |               |      +-- fromFormat to toFormat color conversion
 *     |               +-- fraction of valid range
 *     +-- fraction of full range
 */
void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat,
                  ColorFract& color)
{
    const struct attrib {
        uint32_t     format;
        bool         rgb;
        bool         yuv;
        int          c1Min, c1Low, c1High, c1Max;
        int          c2Min, c2Low, c2High, c2Max;
        int          c3Min, c3Low, c3High, c3Max;
    } attributes[] = {
        {HAL_PIXEL_FORMAT_RGBA_8888, true,  false,
         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
        {HAL_PIXEL_FORMAT_RGBX_8888, true,  false,
         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
        {HAL_PIXEL_FORMAT_RGB_888,   true,  false,
         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
        {HAL_PIXEL_FORMAT_RGB_565,   true,  false,
         0, 0, 31, 31, 0, 0, 63, 63, 0, 0, 31, 31},
        {HAL_PIXEL_FORMAT_BGRA_8888, true,  false,
         0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255},
        {HAL_PIXEL_FORMAT_YV12,      false, true,
         0, 16, 235, 255, 0, 16, 240, 255, 0, 16, 240, 255},
    };

    const struct attrib *fromAttrib;
    for (fromAttrib = attributes; fromAttrib < attributes + NUMA(attributes);
         fromAttrib++) {
        if (fromAttrib->format == fromFormat) { break; }
    }
    if (fromAttrib >= attributes + NUMA(attributes)) {
        testPrintE("hwcTestColorConvert unsupported from format of: %u",
                   fromFormat);
        exit(120);
    }

    const struct attrib *toAttrib;
    for (toAttrib = attributes; toAttrib < attributes + NUMA(attributes);
         toAttrib++) {
        if (toAttrib->format == toFormat) { break; }
    }
    if (toAttrib >= attributes + NUMA(attributes)) {
        testPrintE("hwcTestColorConvert unsupported to format of: %u",
                   toFormat);
        exit(121);
    }

    // Produce black if any of the from components are outside the
    // valid color range
    float c1Val = fromAttrib->c1Min
        + ((float) (fromAttrib->c1Max - fromAttrib->c1Min) * color.c1());
    float c2Val = fromAttrib->c2Min
        + ((float) (fromAttrib->c2Max - fromAttrib->c2Min) * color.c2());
    float c3Val = fromAttrib->c3Min
        + ((float) (fromAttrib->c3Max - fromAttrib->c3Min) * color.c3());
    if ((c1Val < fromAttrib->c1Low) || (c1Val > fromAttrib->c1High)
        || (c2Val < fromAttrib->c2Low) || (c2Val > fromAttrib->c2High)
        || (c3Val < fromAttrib->c3Low) || (c3Val > fromAttrib->c3High)) {

        // Return black
        // Will use representation of black from RGBA8888 graphic format
        // and recursively convert it to the requested graphic format.
        color = ColorFract(0.0, 0.0, 0.0);
        hwcTestColorConvert(HAL_PIXEL_FORMAT_RGBA_8888, toFormat, color);
        return;
    }

    // Within from format, convert from fraction of full range
    // to fraction of valid range
    color = ColorFract((c1Val - fromAttrib->c1Low)
                           / (fromAttrib->c1High - fromAttrib->c1Low),
                       (c2Val - fromAttrib->c2Low)
                           / (fromAttrib->c2High - fromAttrib->c2Low),
                       (c3Val - fromAttrib->c3Low)
                           / (fromAttrib->c3High - fromAttrib->c3Low));

    // If needed perform RGB to YUV conversion
    float wr = 0.2126, wg = 0.7152, wb = 0.0722; // ITU709 recommended constants
    if (fromAttrib->rgb && toAttrib->yuv) {
        float r = color.c1(), g = color.c2(), b = color.c3();
        float y = wr * r + wg * g + wb * b;
        float u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5;
        float v = 0.5 * ((r - y) / (1.0 - wr)) + 0.5;

        // Produce black if color is outside the YUV gamut
        if ((y < 0.0) || (y > 1.0)
            || (u < 0.0) || (u > 1.0)
            || (v < 0.0) || (v > 1.0)) {
            y = 0.0;
            u = v = 0.5;
        }

        color = ColorFract(y, u, v);
    }

    // If needed perform YUV to RGB conversion
    // Equations determined from the ITU709 equations for RGB to YUV
    // conversion, plus the following algebra:
    //
    //   u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5
    //   0.5 * ((b - y) / (1.0 - wb)) = u - 0.5
    //   (b - y) / (1.0 - wb) = 2 * (u - 0.5)
    //   b - y = 2 * (u - 0.5) * (1.0 - wb)
    //   b = 2 * (u - 0.5) * (1.0 - wb) + y
    //
    //   v = 0.5 * ((r -y) / (1.0 - wr)) + 0.5
    //   0.5 * ((r - y) / (1.0 - wr)) = v - 0.5
    //   (r - y) / (1.0 - wr) = 2 * (v - 0.5)
    //   r - y = 2 * (v - 0.5) * (1.0 - wr)
    //   r = 2 * (v - 0.5) * (1.0 - wr) + y
    //
    //   y = wr * r + wg * g + wb * b
    //   wr * r + wg * g + wb * b = y
    //   wg * g = y - wr * r - wb * b
    //   g = (y - wr * r - wb * b) / wg
    if (fromAttrib->yuv && toAttrib->rgb) {
        float y = color.c1(), u = color.c2(), v = color.c3();
        float r = 2.0 * (v - 0.5) * (1.0 - wr) + y;
        float b = 2.0 * (u - 0.5) * (1.0 - wb) + y;
        float g = (y - wr * r - wb * b) / wg;

        // Produce black if color is outside the RGB gamut
        if ((r < 0.0) || (r > 1.0)
            || (g < 0.0) || (g > 1.0)
            || (b < 0.0) || (b > 1.0)) {
            r = g = b = 0.0;
        }

        color = ColorFract(r, g, b);
    }

    // Within to format, convert from fraction of valid range
    // to fraction of full range
    c1Val = (toAttrib->c1Low
        + (float) (toAttrib->c1High - toAttrib->c1Low) * color.c1());
    c2Val = (toAttrib->c1Low
        + (float) (toAttrib->c2High - toAttrib->c2Low) * color.c2());
    c3Val = (toAttrib->c1Low
        + (float) (toAttrib->c3High - toAttrib->c3Low) * color.c3());
    color = ColorFract((float) (c1Val - toAttrib->c1Min)
                           / (float) (toAttrib->c1Max - toAttrib->c1Min),
                       (float) (c2Val - toAttrib->c2Min)
                           / (float) (toAttrib->c2Max - toAttrib->c2Min),
                       (float) (c3Val - toAttrib->c3Min)
                           / (float) (toAttrib->c3Max - toAttrib->c3Min));
}

// TODO: Use PrintGLString, CechckGlError, and PrintEGLConfiguration
//       from libglTest
static void printGLString(const char *name, GLenum s)
{
    const char *v = (const char *) glGetString(s);

    if (v == NULL) {
        testPrintI("GL %s unknown", name);
    } else {
        testPrintI("GL %s = %s", name, v);
    }
}

static void checkEglError(const char* op, EGLBoolean returnVal)
{
    if (returnVal != EGL_TRUE) {
        testPrintE("%s() returned %d", op, returnVal);
    }

    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
            = eglGetError()) {
        testPrintE("after %s() eglError %s (0x%x)",
                   op, EGLUtils::strerror(error), error);
    }
}

static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config)
{

#define X(VAL) {VAL, #VAL}
    struct {EGLint attribute; const char* name;} names[] = {
    X(EGL_BUFFER_SIZE),
    X(EGL_ALPHA_SIZE),
    X(EGL_BLUE_SIZE),
    X(EGL_GREEN_SIZE),
    X(EGL_RED_SIZE),
    X(EGL_DEPTH_SIZE),
    X(EGL_STENCIL_SIZE),
    X(EGL_CONFIG_CAVEAT),
    X(EGL_CONFIG_ID),
    X(EGL_LEVEL),
    X(EGL_MAX_PBUFFER_HEIGHT),
    X(EGL_MAX_PBUFFER_PIXELS),
    X(EGL_MAX_PBUFFER_WIDTH),
    X(EGL_NATIVE_RENDERABLE),
    X(EGL_NATIVE_VISUAL_ID),
    X(EGL_NATIVE_VISUAL_TYPE),
    X(EGL_SAMPLES),
    X(EGL_SAMPLE_BUFFERS),
    X(EGL_SURFACE_TYPE),
    X(EGL_TRANSPARENT_TYPE),
    X(EGL_TRANSPARENT_RED_VALUE),
    X(EGL_TRANSPARENT_GREEN_VALUE),
    X(EGL_TRANSPARENT_BLUE_VALUE),
    X(EGL_BIND_TO_TEXTURE_RGB),
    X(EGL_BIND_TO_TEXTURE_RGBA),
    X(EGL_MIN_SWAP_INTERVAL),
    X(EGL_MAX_SWAP_INTERVAL),
    X(EGL_LUMINANCE_SIZE),
    X(EGL_ALPHA_MASK_SIZE),
    X(EGL_COLOR_BUFFER_TYPE),
    X(EGL_RENDERABLE_TYPE),
    X(EGL_CONFORMANT),
   };
#undef X

    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
        EGLint value = -1;
        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute,
                                              &value);
        EGLint error = eglGetError();
        if (returnVal && error == EGL_SUCCESS) {
            testPrintI(" %s: %d (%#x)", names[j].name, value, value);
        }
    }
    testPrintI("");
}
