/*
 * 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 <sstream>
#include <string>

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

#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 checkGlError(const char* op);
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;

    int rv;

    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++) {
            uint32_t val = pixel;
            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 checkGlError(const char* op)
{
    for (GLint error = glGetError(); error; error
            = glGetError()) {
        testPrintE("after %s() glError (0x%x)", op, 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("");
}
