/*
 * 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);
    }

    EGLNativeWindowType window = 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_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(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_layer_list_t *hwcTestCreateLayerList(size_t numLayers)
{
    hwc_layer_list_t *list;

    size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t);
    if ((list = (hwc_layer_list_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_layer_list_t *list)
{
    free(list);
}

// Display the settings of the layer list pointed to by list
void hwcTestDisplayList(hwc_layer_list_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_layer_list_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_layer_list_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_RGBA_5551, true , 2,  0, 5,  5, 5, 10, 5, 15, 1},
        {HAL_PIXEL_FORMAT_RGBA_4444, false, 2, 12, 4,  0, 4,  4, 4,  8, 4},
        {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},
        {HAL_PIXEL_FORMAT_RGBA_5551,  2},
        {HAL_PIXEL_FORMAT_RGBA_4444,  2},
    };

    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_RGBA_5551, true,  false,
         0, 0, 31, 31, 0, 0, 31, 31, 0, 0, 31, 31},
        {HAL_PIXEL_FORMAT_RGBA_4444, true,  false,
         0, 0, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15},
        {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("");
}
