/*
 * 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 Commit Points
 *
 * Synopsis
 *   hwcCommit [options] graphicFormat ...
 *     options:
 *       -s [width, height] - Starting dimension
 *       -v - Verbose
 *
 *      graphic formats:
 *        RGBA8888 (reference frame default)
 *        RGBX8888
 *        RGB888
 *        RGB565
 *        BGRA8888
 *        RGBA5551
 *        RGBA4444
 *        YV12
 *
 * Description
 *   The Hardware Composer (HWC) Commit test is a benchmark that
 *   discovers the points at which the HWC will commit to rendering an
 *   overlay(s).  Before rendering a set of overlays, the HWC is shown
 *   the list through a prepare call.  During the prepare call the HWC
 *   is able to examine the list and specify which overlays it is able
 *   to handle.  The overlays that it can't handle are typically composited
 *   by a higher level (e.g. Surface Flinger) and then the original list
 *   plus a composit of what HWC passed on are provided back to the HWC
 *   for rendering.
 *
 *   Once an implementation of the HWC has been shipped, a regression would
 *   likely occur if a latter implementation started passing on conditions
 *   that it used to commit to.  The primary purpose of this benchmark
 *   is the automated discovery of the commit points, where an implementation
 *   is on the edge between committing and not committing.  These are commonly
 *   referred to as commit points.  Between implementations changes to the
 *   commit points are allowed, as long as they improve what the HWC commits
 *   to.  Once an implementation of the HWC is shipped, the commit points are
 *   not allowed to regress in future implementations.
 *
 *   This benchmark takes a sampling and then adjusts until it finds a
 *   commit point.  It doesn't exhaustively check all possible conditions,
 *   which do to the number of combinations would be impossible.  Instead
 *   it starts its search from a starting dimension, that can be changed
 *   via the -s option.  The search is also bounded by a set of search
 *   limits, that are hard-coded into a structure of constants named
 *   searchLimits.  Results that happen to reach a searchLimit are prefixed
 *   with >=, so that it is known that the value could possibly be larger.
 *
 *   Measurements are made for each of the graphic formats specified as
 *   positional parameters on the command-line.  If no graphic formats
 *   are specified on the command line, then by default measurements are
 *   made and reported for each of the known graphic format.
 */

#include <algorithm>
#include <assert.h>
#include <cerrno>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <istream>
#include <libgen.h>
#include <list>
#include <sched.h>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <vector>

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <ui/FramebufferNativeWindow.h>
#include <ui/GraphicBuffer.h>

#define LOG_TAG "hwcCommitTest"
#include <utils/Log.h>
#include <testUtil.h>

#include <hardware/hwcomposer.h>

#include <glTestLib.h>
#include "hwcTestLib.h"

using namespace std;
using namespace android;

// Defaults
const HwcTestDim defaultStartDim = HwcTestDim(100, 100);
const bool defaultVerbose = false;

const uint32_t   defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
const int32_t    defaultTransform = 0;
const uint32_t   defaultBlend = HWC_BLENDING_NONE;
const ColorFract defaultColor(0.5, 0.5, 0.5);
const float      defaultAlpha = 1.0; // Opaque
const HwcTestDim defaultSourceDim(1, 1);
const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1};
const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100};

// Global Constants
const uint32_t printFieldWidth = 2;
const struct searchLimits {
    uint32_t   numOverlays;
    HwcTestDim sourceCrop;
} searchLimits = {
    10,
    HwcTestDim(3000, 2000),
};
const struct transformType {
    const char *desc;
    uint32_t id;
} transformType[] = {
    {"fliph",  HWC_TRANSFORM_FLIP_H},
    {"flipv",  HWC_TRANSFORM_FLIP_V},
    {"rot90",  HWC_TRANSFORM_ROT_90},
    {"rot180", HWC_TRANSFORM_ROT_180},
    {"rot270", HWC_TRANSFORM_ROT_270},
};
const struct blendType {
    const char *desc;
    uint32_t id;
} blendType[] = {
    {"none", HWC_BLENDING_NONE},
    {"premult", HWC_BLENDING_PREMULT},
    {"coverage", HWC_BLENDING_COVERAGE},
};

// Defines
#define MAXCMD               200
#define CMD_STOP_FRAMEWORK   "stop 2>&1"
#define CMD_START_FRAMEWORK  "start 2>&1"

// Macros
#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array

// Local types
class Rectangle {
public:
    Rectangle(uint32_t graphicFormat = defaultFormat,
              HwcTestDim dfDim = HwcTestDim(1, 1),
              HwcTestDim sDim = HwcTestDim(1, 1));
    void setSourceDim(HwcTestDim dim);

    uint32_t     format;
    uint32_t     transform;
    int32_t      blend;
    ColorFract   color;
    float        alpha;
    HwcTestDim   sourceDim;
    struct hwc_rect   sourceCrop;
    struct hwc_rect   displayFrame;
};

class Range {
public:
    Range(void) : _l(0), _u(0) {}
    Range(uint32_t lower, uint32_t upper) : _l(lower), _u(upper) {}
    uint32_t lower(void) { return _l; }
    uint32_t upper(void) { return _u; }

    operator string();

private:
    uint32_t _l; // lower
    uint32_t _u; // upper
};

Range::operator string()
{
    ostringstream out;

    out << '[' << _l << ", " << _u << ']';

    return out.str();
}

class Rational {
public:
    Rational(void) : _n(0), _d(1) {}
    Rational(uint32_t n, uint32_t d) : _n(n), _d(d) {}
    uint32_t numerator(void) { return _n; }
    uint32_t denominator(void) { return _d; }
    void setNumerator(uint32_t numerator) { _n = numerator; }

    bool operator==(const Rational& other) const;
    bool operator!=(const Rational& other) const { return !(*this == other); }
    bool operator<(const Rational& other) const;
    bool operator>(const Rational& other) const {
        return (!(*this == other) && !(*this < other));
    }
    static void double2Rational(double f, Range nRange, Range dRange,
                               Rational& lower, Rational& upper);
        
    operator string() const;
    operator double() const { return (double) _n / (double) _d; }


private:
    uint32_t _n;
    uint32_t _d;
};

// Globals
static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE |
        GraphicBuffer::USAGE_SW_WRITE_RARELY;
static hwc_composer_device_1_t *hwcDevice;
static EGLDisplay dpy;
static EGLSurface surface;
static EGLint width, height;
static size_t maxHeadingLen;
static vector<string> formats;

// Measurements
struct meas {
    uint32_t format;
    uint32_t startDimOverlays;
    uint32_t maxNonOverlapping;
    uint32_t maxOverlapping;
    list<uint32_t> transforms;
    list<uint32_t> blends;
    struct displayFrame {
        uint32_t minWidth;
        uint32_t minHeight;
        HwcTestDim minDim;
        uint32_t maxWidth;
        uint32_t maxHeight;
        HwcTestDim maxDim;
    } df;
    struct sourceCrop {
        uint32_t minWidth;
        uint32_t minHeight;
        HwcTestDim minDim;
        uint32_t maxWidth;
        uint32_t maxHeight;
        HwcTestDim maxDim;
        Rational hScale;
        HwcTestDim hScaleBestDf;
        HwcTestDim hScaleBestSc;
        Rational vScale;
        HwcTestDim vScaleBestDf;
        HwcTestDim vScaleBestSc;
    } sc;
    vector<uint32_t> overlapBlendNone;
    vector<uint32_t> overlapBlendPremult;
    vector<uint32_t> overlapBlendCoverage;
};
vector<meas> measurements;

// Function prototypes
uint32_t numOverlays(list<Rectangle>& rectList);
uint32_t maxOverlays(uint32_t format, bool allowOverlap);
list<uint32_t> supportedTransforms(uint32_t format);
list<uint32_t> supportedBlends(uint32_t format);
uint32_t dfMinWidth(uint32_t format);
uint32_t dfMinHeight(uint32_t format);
uint32_t dfMaxWidth(uint32_t format);
uint32_t dfMaxHeight(uint32_t format);
HwcTestDim dfMinDim(uint32_t format);
HwcTestDim dfMaxDim(uint32_t format);
uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim);
uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim);
uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim);
uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim);
HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim);
HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim);
Rational scHScale(uint32_t format,
                  const HwcTestDim& dfMin, const HwcTestDim& dfMax,
                  const HwcTestDim& scMin, const HwcTestDim& scMax,
                  HwcTestDim& outBestDf, HwcTestDim& outBestSc);
Rational scVScale(uint32_t format,
                  const HwcTestDim& dfMin, const HwcTestDim& dfMax,
                  const HwcTestDim& scMin, const HwcTestDim& scMax,
                  HwcTestDim& outBestDf, HwcTestDim& outBestSc);
uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
                        uint32_t backgroundBlend, uint32_t foregroundBlend);
string transformList2str(const list<uint32_t>& transformList);
string blendList2str(const list<uint32_t>& blendList);
void init(void);
void printFormatHeadings(size_t indent);
void printOverlapLine(size_t indent, const string formatStr,
                      const vector<uint32_t>& results);
void printSyntax(const char *cmd);

// Command-line option settings
static bool verbose = defaultVerbose;
static HwcTestDim startDim = defaultStartDim;

/*
 * Main
 *
 * Performs the following high-level sequence of operations:
 *
 *   1. Command-line parsing
 *
 *   2. Form a list of command-line specified graphic formats.  If
 *      no formats are specified, then form a list of all known formats.
 *
 *   3. Stop framework
 *      Only one user at a time is allowed to use the HWC.  Surface
 *      Flinger uses the HWC and is part of the framework.  Need to
 *      stop the framework so that Surface Flinger will stop using
 *      the HWC.
 *   
 *   4. Initialization
 *
 *   5. For each graphic format in the previously formed list perform
 *      measurements on that format and report the results.
 *
 *   6. Start framework
 */
int
main(int argc, char *argv[])
{
    int     rv, opt;
    char   *chptr;
    bool    error;
    string  str;
    char cmd[MAXCMD];
    list<Rectangle> rectList;

    testSetLogCatTag(LOG_TAG);

    // Parse command line arguments
    while ((opt = getopt(argc, argv, "s:v?h")) != -1) {
        switch (opt) {

          case 's': // Start Dimension
            // Use arguments until next starts with a dash
            // or current ends with a > or ]
            str = optarg;
            while (optind < argc) {
                if (*argv[optind] == '-') { break; }
                char endChar = (str.length() > 1) ? str[str.length() - 1] : 0;
                if ((endChar == '>') || (endChar == ']')) { break; }
                str += " " + string(argv[optind++]);
            }
            {
                istringstream in(str);
                startDim = hwcTestParseDim(in, error);
                // Any parse error or characters not used by parser
                if (error
                    || (((unsigned int) in.tellg() != in.str().length())
                        && (in.tellg() != (streampos) -1))) {
                    testPrintE("Invalid command-line specified start "
                               "dimension of: %s", str.c_str());
                    exit(8);
                }
            }
            break;

          case 'v': // Verbose
            verbose = true;
            break;

          case 'h': // Help
          case '?':
          default:
            printSyntax(basename(argv[0]));
            exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
        }
    }

    // Positional parameters
    // Positional parameters provide the names of graphic formats that
    // measurements are to be made on.  Measurements are made on all
    // known graphic formats when no positional parameters are provided.
    if (optind == argc) {
        // No command-line specified graphic formats
        // Add all graphic formats to the list of formats to be measured
        for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
            formats.push_back(hwcTestGraphicFormat[n1].desc);
        }
    } else {
        // Add names of command-line specified graphic formats to the
        // list of formats to be tested
        for (; argv[optind] != NULL; optind++) {
            formats.push_back(argv[optind]);
        }
    }

    // Determine length of longest specified graphic format.
    // This value is used for output formating
    for (vector<string>::iterator it = formats.begin();
         it != formats.end(); ++it) {
         maxHeadingLen = max(maxHeadingLen, it->length());
    }

    // Stop framework
    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
    if (rv >= (signed) sizeof(cmd) - 1) {
        testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK);
        exit(14);
    }
    testExecCmd(cmd);
    testDelay(1.0); // TODO - needs means to query whether asynchronous stop
                    // framework operation has completed.  For now, just wait
                    // a long time.

    testPrintI("startDim: %s", ((string) startDim).c_str());

    init();

    // For each of the graphic formats
    for (vector<string>::iterator itFormat = formats.begin();
         itFormat != formats.end(); ++itFormat) {

        // Locate hwcTestLib structure that describes this format
        const struct hwcTestGraphicFormat *format;
        format = hwcTestGraphicFormatLookup((*itFormat).c_str());
        if (format == NULL) {
            testPrintE("Unknown graphic format of: %s", (*itFormat).c_str());
            exit(1);
        }

        // Display format header
        testPrintI("format: %s", format->desc);

        // Create area to hold the measurements
        struct meas meas;
        struct meas *measPtr;
        meas.format = format->format;
        measurements.push_back(meas);
        measPtr = &measurements[measurements.size() - 1];

        // Start dimension num overlays
        Rectangle rect(format->format, startDim);
        rectList.clear();
        rectList.push_back(rect);
        measPtr->startDimOverlays = numOverlays(rectList);
        testPrintI("  startDimOverlays: %u", measPtr->startDimOverlays);

        // Skip the rest of the measurements, when the start dimension
        // doesn't produce an overlay
        if (measPtr->startDimOverlays == 0) { continue; }

        // Max Overlays
        measPtr->maxNonOverlapping = maxOverlays(format->format, false);
        testPrintI("  max nonOverlapping overlays: %s%u",
                   (measPtr->maxNonOverlapping == searchLimits.numOverlays)
                       ? ">= " : "",
                   measPtr->maxNonOverlapping);
        measPtr->maxOverlapping = maxOverlays(format->format, true);
        testPrintI("  max Overlapping overlays: %s%u",
                   (measPtr->maxOverlapping == searchLimits.numOverlays)
                       ? ">= " : "",
                   measPtr->maxOverlapping);

        // Transforms and blends
        measPtr->transforms = supportedTransforms(format->format);
        testPrintI("  transforms: %s",
                   transformList2str(measPtr->transforms).c_str());
        measPtr->blends = supportedBlends(format->format);
        testPrintI("  blends: %s",
                   blendList2str(measPtr->blends).c_str());

        // Display frame measurements
        measPtr->df.minWidth = dfMinWidth(format->format);
        testPrintI("  dfMinWidth: %u", measPtr->df.minWidth);

        measPtr->df.minHeight = dfMinHeight(format->format);
        testPrintI("  dfMinHeight: %u", measPtr->df.minHeight);

        measPtr->df.maxWidth = dfMaxWidth(format->format);
        testPrintI("  dfMaxWidth: %u", measPtr->df.maxWidth);

        measPtr->df.maxHeight = dfMaxHeight(format->format);
        testPrintI("  dfMaxHeight: %u", measPtr->df.maxHeight);

        measPtr->df.minDim = dfMinDim(format->format);
        testPrintI("  dfMinDim: %s", ((string) measPtr->df.minDim).c_str());

        measPtr->df.maxDim = dfMaxDim(format->format);
        testPrintI("  dfMaxDim: %s", ((string) measPtr->df.maxDim).c_str());

        // Source crop measurements
        measPtr->sc.minWidth = scMinWidth(format->format, measPtr->df.minDim);
        testPrintI("  scMinWidth: %u", measPtr->sc.minWidth);

        measPtr->sc.minHeight = scMinHeight(format->format, measPtr->df.minDim);
        testPrintI("  scMinHeight: %u", measPtr->sc.minHeight);

        measPtr->sc.maxWidth = scMaxWidth(format->format, measPtr->df.maxDim);
        testPrintI("  scMaxWidth: %s%u", (measPtr->sc.maxWidth
                   == searchLimits.sourceCrop.width()) ? ">= " : "",
                   measPtr->sc.maxWidth);

        measPtr->sc.maxHeight = scMaxHeight(format->format, measPtr->df.maxDim);
        testPrintI("  scMaxHeight: %s%u", (measPtr->sc.maxHeight
                   == searchLimits.sourceCrop.height()) ? ">= " : "",
                   measPtr->sc.maxHeight);

        measPtr->sc.minDim = scMinDim(format->format, measPtr->df.minDim);
        testPrintI("  scMinDim: %s", ((string) measPtr->sc.minDim).c_str());

        measPtr->sc.maxDim = scMaxDim(format->format, measPtr->df.maxDim);
        testPrintI("  scMaxDim: %s%s", ((measPtr->sc.maxDim.width()
                         >= searchLimits.sourceCrop.width())
                         || (measPtr->sc.maxDim.width() >=
                         searchLimits.sourceCrop.height())) ? ">= " : "",
                   ((string) measPtr->sc.maxDim).c_str());

        measPtr->sc.hScale = scHScale(format->format,
                                      measPtr->df.minDim, measPtr->df.maxDim,
                                      measPtr->sc.minDim, measPtr->sc.maxDim,
                                      measPtr->sc.hScaleBestDf,
                                      measPtr->sc.hScaleBestSc);
        testPrintI("  scHScale: %s%f",
                   (measPtr->sc.hScale
                       >= Rational(searchLimits.sourceCrop.width(),
                                   measPtr->df.minDim.width())) ? ">= " : "",
                   (double) measPtr->sc.hScale);
        testPrintI("    HScale Best Display Frame: %s",
                   ((string) measPtr->sc.hScaleBestDf).c_str());
        testPrintI("    HScale Best Source Crop: %s",
                   ((string) measPtr->sc.hScaleBestSc).c_str());

        measPtr->sc.vScale = scVScale(format->format,
                                      measPtr->df.minDim, measPtr->df.maxDim,
                                      measPtr->sc.minDim, measPtr->sc.maxDim,
                                      measPtr->sc.vScaleBestDf,
                                      measPtr->sc.vScaleBestSc);
        testPrintI("  scVScale: %s%f",
                   (measPtr->sc.vScale
                       >= Rational(searchLimits.sourceCrop.height(),
                                   measPtr->df.minDim.height())) ? ">= " : "",
                   (double) measPtr->sc.vScale);
        testPrintI("    VScale Best Display Frame: %s",
                   ((string) measPtr->sc.vScaleBestDf).c_str());
        testPrintI("    VScale Best Source Crop: %s",
                   ((string) measPtr->sc.vScaleBestSc).c_str());

        // Overlap two graphic formats and different blends
        // Results displayed after all overlap measurments with
        // current format in the foreground
        // TODO: make measurments with background blend other than
        //       none.  All of these measurements are done with a
        //       background blend of HWC_BLENDING_NONE, with the
        //       blend type of the foregound being varied.
        uint32_t foregroundFormat = format->format;
        for (vector<string>::iterator it = formats.begin();
             it != formats.end(); ++it) {
            uint32_t num;

            const struct hwcTestGraphicFormat *backgroundFormatPtr
                = hwcTestGraphicFormatLookup((*it).c_str());
            uint32_t backgroundFormat = backgroundFormatPtr->format;

            num = numOverlapping(backgroundFormat, foregroundFormat,
                                 HWC_BLENDING_NONE, HWC_BLENDING_NONE);
            measPtr->overlapBlendNone.push_back(num);

            num = numOverlapping(backgroundFormat, foregroundFormat,
                                 HWC_BLENDING_NONE, HWC_BLENDING_PREMULT);
            measPtr->overlapBlendPremult.push_back(num);

            num = numOverlapping(backgroundFormat, foregroundFormat,
                                 HWC_BLENDING_NONE, HWC_BLENDING_COVERAGE);
            measPtr->overlapBlendCoverage.push_back(num);
        }

    }

    // Display overlap results
    size_t indent = 2;
    testPrintI("overlapping blend: none");
    printFormatHeadings(indent);
    for (vector<string>::iterator it = formats.begin();
         it != formats.end(); ++it) {
        printOverlapLine(indent, *it, measurements[it
                         - formats.begin()].overlapBlendNone);
    }
    testPrintI("");

    testPrintI("overlapping blend: premult");
    printFormatHeadings(indent);
    for (vector<string>::iterator it = formats.begin();
         it != formats.end(); ++it) {
        printOverlapLine(indent, *it, measurements[it
                         - formats.begin()].overlapBlendPremult);
    }
    testPrintI("");

    testPrintI("overlapping blend: coverage");
    printFormatHeadings(indent);
    for (vector<string>::iterator it = formats.begin();
         it != formats.end(); ++it) {
        printOverlapLine(indent, *it, measurements[it
                         - formats.begin()].overlapBlendCoverage);
    }
    testPrintI("");

    // Start framework
    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
    if (rv >= (signed) sizeof(cmd) - 1) {
        testPrintE("Command too long for: %s", CMD_START_FRAMEWORK);
        exit(21);
    }
    testExecCmd(cmd);

    return 0;
}

// Determine the maximum number of overlays that are all of the same format
// that the HWC will commit to.  If allowOverlap is true, then the rectangles
// are laid out on a diagonal starting from the upper left corner.  With
// each rectangle adjust one pixel to the right and one pixel down.
// When allowOverlap is false, the rectangles are tiled in column major
// order.  Note, column major ordering is used so that the initial rectangles
// are all on different horizontal scan rows.  It is common that hardware
// has limits on the number of objects it can handle on any single row.
uint32_t maxOverlays(uint32_t format, bool allowOverlap)
{
    unsigned int max = 0;

    for (unsigned int numRects = 1; numRects <= searchLimits.numOverlays;
         numRects++) {
        list<Rectangle> rectList;

        for (unsigned int x = 0;
             (x + startDim.width()) < (unsigned int) width;
             x += (allowOverlap) ? 1 : startDim.width()) {
            for (unsigned int y = 0;
                 (y + startDim.height()) < (unsigned int) height;
                 y += (allowOverlap) ? 1 : startDim.height()) {
                Rectangle rect(format, startDim, startDim);
                rect.displayFrame.left = x;
                rect.displayFrame.top = y;
                rect.displayFrame.right = x + startDim.width();
                rect.displayFrame.bottom = y + startDim.height();

                rectList.push_back(rect);

                if (rectList.size() >= numRects) { break; }
            }
            if (rectList.size() >= numRects) { break; }
        }

        uint32_t num = numOverlays(rectList);
        if (num > max) { max = num; }
    }

    return max;
}

// Measures what transforms (i.e. flip horizontal, rotate 180) are
// supported by the specified format
list<uint32_t> supportedTransforms(uint32_t format)
{
    list<uint32_t> rv;
    list<Rectangle> rectList;
    Rectangle rect(format, startDim);

    // For each of the transform types
    for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
        unsigned int id = transformType[idx].id;

        rect.transform = id;
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);

        if (num == 1) {
            rv.push_back(id);
        }
    }

    return rv;
}

// Determines which types of blends (i.e. none, premult, coverage) are
// supported by the specified format
list<uint32_t> supportedBlends(uint32_t format)
{
    list<uint32_t> rv;
    list<Rectangle> rectList;
    Rectangle rect(format, startDim);

    // For each of the blend types
    for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
        unsigned int id = blendType[idx].id;

        rect.blend = id;
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);

        if (num == 1) {
            rv.push_back(id);
        }
    }

    return rv;
}

// Determines the minimum width of any display frame of the given format
// that the HWC will commit to.
uint32_t dfMinWidth(uint32_t format)
{
    uint32_t w;
    list<Rectangle> rectList;

    for (w = 1; w <= startDim.width(); w++) {
        HwcTestDim dim(w, startDim.height());
        Rectangle rect(format, dim);
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return w;
        }
    }
    if (w > startDim.width()) {
        testPrintE("Failed to locate display frame min width");
        exit(33);
    }

    return w;
}

// Display frame minimum height
uint32_t dfMinHeight(uint32_t format)
{
    uint32_t h;
    list<Rectangle> rectList;

    for (h = 1; h <= startDim.height(); h++) {
        HwcTestDim dim(startDim.width(), h);
        Rectangle rect(format, dim);
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return h;
        }
    }
    if (h > startDim.height()) {
        testPrintE("Failed to locate display frame min height");
        exit(34);
    }

    return h;
}

// Display frame maximum width
uint32_t dfMaxWidth(uint32_t format)
{
    uint32_t w;
    list<Rectangle> rectList;

    for (w = width; w >= startDim.width(); w--) {
        HwcTestDim dim(w, startDim.height());
        Rectangle rect(format, dim);
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return w;
        }
    }
    if (w < startDim.width()) {
        testPrintE("Failed to locate display frame max width");
        exit(35);
    }

    return w;
}

// Display frame maximum height
uint32_t dfMaxHeight(uint32_t format)
{
    uint32_t h;

    for (h = height; h >= startDim.height(); h--) {
        HwcTestDim dim(startDim.width(), h);
        Rectangle rect(format, dim);
        list<Rectangle> rectList;
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return h;
        }
    }
    if (h < startDim.height()) {
        testPrintE("Failed to locate display frame max height");
        exit(36);
    }

    return h;
}

// Determine the minimum number of pixels that the HWC will ever commit to.
// Note, this might be different that dfMinWidth * dfMinHeight, in that this
// function adjusts both the width and height from the starting dimension.
HwcTestDim dfMinDim(uint32_t format)
{
    uint64_t bestMinPixels = 0;
    HwcTestDim bestDim;
    bool bestSet = false; // True when value has been assigned to
                          // bestMinPixels and bestDim

    bool origVerbose = verbose;  // Temporarily turn off verbose
    verbose = false;
    for (uint32_t w = 1; w <= startDim.width(); w++) {
        for (uint32_t h = 1; h <= startDim.height(); h++) {
            if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
                break;
            }

            HwcTestDim dim(w, h);
            Rectangle rect(format, dim);
            list<Rectangle> rectList;
            rectList.push_back(rect);
            uint32_t num = numOverlays(rectList);
            if (num > 0) {
                uint64_t pixels = dim.width() * dim.height();
                if (!bestSet || (pixels < bestMinPixels)) {
                    bestMinPixels = pixels;
                    bestDim = dim;
                    bestSet = true;
                }
            }
        }
    }
    verbose = origVerbose;

    if (!bestSet) {
        testPrintE("Unable to locate display frame min dimension");
        exit(20);
    }

    return bestDim;
}

// Display frame maximum dimension
HwcTestDim dfMaxDim(uint32_t format)
{
    uint64_t bestMaxPixels = 0;
    HwcTestDim bestDim;
    bool bestSet = false; // True when value has been assigned to
                          // bestMaxPixels and bestDim;

    // Potentially increase benchmark performance by first checking
    // for the common case of supporting a full display frame.
    HwcTestDim dim(width, height);
    Rectangle rect(format, dim);
    list<Rectangle> rectList;
    rectList.push_back(rect);
    uint32_t num = numOverlays(rectList);
    if (num == 1) { return dim; }

    // TODO: Use a binary search
    bool origVerbose = verbose;  // Temporarily turn off verbose
    verbose = false;
    for (uint32_t w = startDim.width(); w <= (uint32_t) width; w++) {
        for (uint32_t h = startDim.height(); h <= (uint32_t) height; h++) {
            if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }

            HwcTestDim dim(w, h);
            Rectangle rect(format, dim);
            list<Rectangle> rectList;
            rectList.push_back(rect);
            uint32_t num = numOverlays(rectList);
            if (num > 0) {
                uint64_t pixels = dim.width() * dim.height();
                if (!bestSet || (pixels > bestMaxPixels)) {
                    bestMaxPixels = pixels;
                    bestDim = dim;
                    bestSet = true;
                }
            }
        }
    }
    verbose = origVerbose;

    if (!bestSet) {
        testPrintE("Unable to locate display frame max dimension");
        exit(21);
    }

    return bestDim;
}

// Source crop minimum width
uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim)
{
    uint32_t w;
    list<Rectangle> rectList;

    // Source crop frame min width
    for (w = 1; w <= dfDim.width(); w++) {
        Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return w;
        }
    }
    testPrintE("Failed to locate source crop min width");
    exit(35);
}

// Source crop minimum height
uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim)
{
    uint32_t h;
    list<Rectangle> rectList;

    for (h = 1; h <= dfDim.height(); h++) {
        Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return h;
        }
    }
    testPrintE("Failed to locate source crop min height");
    exit(36);
}

// Source crop maximum width
uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim)
{
    uint32_t w;
    list<Rectangle> rectList;

    for (w = searchLimits.sourceCrop.width(); w >= dfDim.width(); w--) {
        Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height()));
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return w;
        }
    }
    testPrintE("Failed to locate source crop max width");
    exit(35);
}

// Source crop maximum height
uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim)
{
    uint32_t h;
    list<Rectangle> rectList;

    for (h = searchLimits.sourceCrop.height(); h >= dfDim.height(); h--) {
        Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h));
        rectList.clear();
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);
        if (num > 0) {
            return h;
        }
    }
    testPrintE("Failed to locate source crop max height");
    exit(36);
}

// Source crop minimum dimension
// Discovers the source crop with the least number of pixels that the
// HWC will commit to.  Note, this may be different from scMinWidth
// * scMinHeight, in that this function searches for a combination of
// width and height.  While the other routines always keep one of the
// dimensions equal to the corresponding start dimension.
HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim)
{
    uint64_t bestMinPixels = 0;
    HwcTestDim bestDim;
    bool bestSet = false; // True when value has been assigned to
                          // bestMinPixels and bestDim

    bool origVerbose = verbose;  // Temporarily turn off verbose
    verbose = false;
    for (uint32_t w = 1; w <= dfDim.width(); w++) {
        for (uint32_t h = 1; h <= dfDim.height(); h++) {
            if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) {
                break;
            }

            HwcTestDim dim(w, h);
            Rectangle rect(format, dfDim, HwcTestDim(w, h));
            list<Rectangle> rectList;
            rectList.push_back(rect);
            uint32_t num = numOverlays(rectList);
            if (num > 0) {
                uint64_t pixels = dim.width() * dim.height();
                if (!bestSet || (pixels < bestMinPixels)) {
                    bestMinPixels = pixels;
                    bestDim = dim;
                    bestSet = true;
                }
            }
        }
    }
    verbose = origVerbose;

    if (!bestSet) {
        testPrintE("Unable to locate source crop min dimension");
        exit(20);
    }

    return bestDim;
}

// Source crop maximum dimension
HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim)
{
    uint64_t bestMaxPixels = 0;
    HwcTestDim bestDim;
    bool bestSet = false; // True when value has been assigned to
                          // bestMaxPixels and bestDim;

    // Potentially increase benchmark performance by first checking
    // for the common case of supporting the maximum checked source size
    HwcTestDim dim = searchLimits.sourceCrop;
    Rectangle rect(format, dfDim, searchLimits.sourceCrop);
    list<Rectangle> rectList;
    rectList.push_back(rect);
    uint32_t num = numOverlays(rectList);
    if (num == 1) { return dim; }

    // TODO: Use a binary search
    bool origVerbose = verbose;  // Temporarily turn off verbose
    verbose = false;
    for (uint32_t w = dfDim.width();
         w <= searchLimits.sourceCrop.width(); w++) {
        for (uint32_t h = dfDim.height();
             h <= searchLimits.sourceCrop.height(); h++) {
            if (bestSet && ((w * h) <= bestMaxPixels)) { continue; }

            HwcTestDim dim(w, h);
            Rectangle rect(format, dfDim, dim);
            list<Rectangle> rectList;
            rectList.push_back(rect);
            uint32_t num = numOverlays(rectList);
            if (num > 0) {
                uint64_t pixels = dim.width() * dim.height();
                if (!bestSet || (pixels > bestMaxPixels)) {
                    bestMaxPixels = pixels;
                    bestDim = dim;
                    bestSet = true;
                }
            }
        }
    }
    verbose = origVerbose;

    if (!bestSet) {
        testPrintE("Unable to locate source crop max dimension");
        exit(21);
    }

    return bestDim;
}

// Source crop horizontal scale
// Determines the maximum factor by which the source crop can be larger
// that the display frame.  The commit point is discovered through a
// binary search of rational numbers.  The numerator in each of the
// rational numbers contains the dimension for the source crop, while
// the denominator specifies the dimension for the display frame.  On
// each pass of the binary search the mid-point between the greatest
// point committed to (best) and the smallest point in which a commit
// has failed is calculated.  This mid-point is then passed to a function
// named double2Rational, which determines the closest rational numbers
// just below and above the mid-point.  By default the lower rational
// number is used for the scale factor on the next pass of the binary
// search.  The upper value is only used when best is already equal
// to the lower value.  This only occurs when the lower value has already
// been tried.
Rational scHScale(uint32_t format,
                      const HwcTestDim& dfMin, const HwcTestDim& dfMax,
                      const HwcTestDim& scMin, const HwcTestDim& scMax,
                      HwcTestDim& outBestDf, HwcTestDim& outBestSc)
{
    HwcTestDim scDim, dfDim; // Source crop and display frame dimension
    Rational best(0, 1), minBad;  // Current bounds for a binary search
                                  // MinGood is set below the lowest
                                  // possible scale.  The value of minBad,
                                  // will be set by the first pass
                                  // of the binary search.

    // Perform the passes of the binary search
    bool firstPass = true;
    do {
        // On first pass try the maximum scale within the search limits
        if (firstPass) {
            // Try the maximum possible scale, within the search limits
            scDim = HwcTestDim(searchLimits.sourceCrop.width(), scMin.height());
            dfDim = dfMin;
        } else {
            // Subsequent pass
            // Halve the difference between best and minBad.
            Rational lower, upper, selected;

            // Try the closest ratio halfway between minBood and minBad;
            // TODO: Avoid rounding issue by using Rational type for
            //       midpoint.  For now will use double, which should
            //       have more than sufficient resolution.
            double mid = (double) best
                         + ((double) minBad - (double) best) / 2.0;
            Rational::double2Rational(mid,
                            Range(scMin.width(), scMax.width()),
                            Range(dfMin.width(), dfMax.width()),
                            lower, upper);
            if (((lower == best) && (upper == minBad))) {
                return best;
            }

            // Use lower value unless its already been tried
            selected = (lower != best) ? lower : upper;

            // Assign the size of the source crop and display frame
            // from the selected ratio of source crop to display frame.
            scDim = HwcTestDim(selected.numerator(), scMin.height());
            dfDim = HwcTestDim(selected.denominator(), dfMin.height());
        }

        // See if the HWC will commit to this combination
        Rectangle rect(format, dfDim, scDim);
        list<Rectangle> rectList;
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);

        if (verbose) {
            testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
                       num, (float) Rational(scDim.width(), dfDim.width()),
                       ((string) dfDim).c_str(), ((string) scDim).c_str());
        }
        if (num == 1) {
            // HWC committed to the combination
            // This is the best scale factor seen so far.  Report the
            // dimensions to the caller, in case nothing better is seen.
            outBestDf = dfDim;
            outBestSc = scDim;

            // Success on the first pass means the largest possible scale
            // is supported, in which case no need to search any further.
            if (firstPass) { return Rational(scDim.width(), dfDim.width()); }

            // Update the lower bound of the binary search
            best = Rational(scDim.width(), dfDim.width());
        } else {
            // HWC didn't commit to this combination, so update the
            // upper bound of the binary search.
            minBad = Rational(scDim.width(), dfDim.width());
        }

        firstPass = false;
    } while (best != minBad);

    return best;
}

// Source crop vertical scale
// Determines the maximum factor by which the source crop can be larger
// that the display frame.  The commit point is discovered through a
// binary search of rational numbers.  The numerator in each of the
// rational numbers contains the dimension for the source crop, while
// the denominator specifies the dimension for the display frame.  On
// each pass of the binary search the mid-point between the greatest
// point committed to (best) and the smallest point in which a commit
// has failed is calculated.  This mid-point is then passed to a function
// named double2Rational, which determines the closest rational numbers
// just below and above the mid-point.  By default the lower rational
// number is used for the scale factor on the next pass of the binary
// search.  The upper value is only used when best is already equal
// to the lower value.  This only occurs when the lower value has already
// been tried.
Rational scVScale(uint32_t format,
                      const HwcTestDim& dfMin, const HwcTestDim& dfMax,
                      const HwcTestDim& scMin, const HwcTestDim& scMax,
                      HwcTestDim& outBestDf, HwcTestDim& outBestSc)
{
    HwcTestDim scDim, dfDim; // Source crop and display frame dimension
    Rational best(0, 1), minBad;  // Current bounds for a binary search
                                  // MinGood is set below the lowest
                                  // possible scale.  The value of minBad,
                                  // will be set by the first pass
                                  // of the binary search.

    // Perform the passes of the binary search
    bool firstPass = true;
    do {
        // On first pass try the maximum scale within the search limits
        if (firstPass) {
            // Try the maximum possible scale, within the search limits
            scDim = HwcTestDim(scMin.width(), searchLimits.sourceCrop.height());
            dfDim = dfMin;
        } else {
            // Subsequent pass
            // Halve the difference between best and minBad.
            Rational lower, upper, selected;

            // Try the closest ratio halfway between minBood and minBad;
            // TODO: Avoid rounding issue by using Rational type for
            //       midpoint.  For now will use double, which should
            //       have more than sufficient resolution.
            double mid = (double) best
                         + ((double) minBad - (double) best) / 2.0;
            Rational::double2Rational(mid,
                            Range(scMin.height(), scMax.height()),
                            Range(dfMin.height(), dfMax.height()),
                            lower, upper);
            if (((lower == best) && (upper == minBad))) {
                return best;
            }

            // Use lower value unless its already been tried
            selected = (lower != best) ? lower : upper;

            // Assign the size of the source crop and display frame
            // from the selected ratio of source crop to display frame.
            scDim = HwcTestDim(scMin.width(), selected.numerator());
            dfDim = HwcTestDim(dfMin.width(), selected.denominator());
        }

        // See if the HWC will commit to this combination
        Rectangle rect(format, dfDim, scDim);
        list<Rectangle> rectList;
        rectList.push_back(rect);
        uint32_t num = numOverlays(rectList);

        if (verbose) {
            testPrintI("  scHscale num: %u scale: %f dfDim: %s scDim: %s",
                       num, (float) Rational(scDim.height(), dfDim.height()),
                       ((string) dfDim).c_str(), ((string) scDim).c_str());
        }
        if (num == 1) {
            // HWC committed to the combination
            // This is the best scale factor seen so far.  Report the
            // dimensions to the caller, in case nothing better is seen.
            outBestDf = dfDim;
            outBestSc = scDim;

            // Success on the first pass means the largest possible scale
            // is supported, in which case no need to search any further.
            if (firstPass) { return Rational(scDim.height(), dfDim.height()); }

            // Update the lower bound of the binary search
            best = Rational(scDim.height(), dfDim.height());
        } else {
            // HWC didn't commit to this combination, so update the
            // upper bound of the binary search.
            minBad = Rational(scDim.height(), dfDim.height());
        }

        firstPass = false;
    } while (best != minBad);

    return best;
}

uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat,
                        uint32_t backgroundBlend, uint32_t foregroundBlend)
{
    list<Rectangle> rectList;

    Rectangle background(backgroundFormat, startDim, startDim);
    background.blend = backgroundBlend;
    rectList.push_back(background);

    // TODO: Handle cases where startDim is so small that adding 5
    //       causes frames not to overlap.
    // TODO: Handle cases where startDim is so large that adding 5
    //       cause a portion or all of the foreground displayFrame
    //       to be off the display.
    Rectangle foreground(foregroundFormat, startDim, startDim);
    foreground.displayFrame.left += 5;
    foreground.displayFrame.top += 5;
    foreground.displayFrame.right += 5;
    foreground.displayFrame.bottom += 5;
    background.blend = foregroundBlend;
    rectList.push_back(foreground);

    uint32_t num = numOverlays(rectList);

    return num;
}

Rectangle::Rectangle(uint32_t graphicFormat, HwcTestDim dfDim,
                     HwcTestDim sDim) :
    format(graphicFormat), transform(defaultTransform),
    blend(defaultBlend), color(defaultColor), alpha(defaultAlpha),
    sourceCrop(sDim), displayFrame(dfDim)
{
    // Set source dimension
    // Can't use a base initializer, because the setting of format
    // must be done before setting the sourceDimension.
    setSourceDim(sDim);
}

void Rectangle::setSourceDim(HwcTestDim dim)
{
    this->sourceDim = dim;

    const struct hwcTestGraphicFormat *attrib;
    attrib = hwcTestGraphicFormatLookup(this->format);
    if (attrib != NULL) {
        if (sourceDim.width() % attrib->wMod) {
            sourceDim.setWidth(sourceDim.width() + attrib->wMod
            - (sourceDim.width() % attrib->wMod));
        }
        if (sourceDim.height() % attrib->hMod) {
            sourceDim.setHeight(sourceDim.height() + attrib->hMod
            - (sourceDim.height() % attrib->hMod));
        }
    }
}

// Rational member functions
bool Rational::operator==(const Rational& other) const
{
    if (((uint64_t) _n * other._d)
        == ((uint64_t) _d * other._n)) { return true; }

    return false;
}

bool Rational::operator<(const Rational& other) const
{
    if (((uint64_t) _n * other._d)
        < ((uint64_t) _d * other._n)) { return true; }

    return false;
}

Rational::operator string() const
{
    ostringstream out;

    out << _n << '/' << _d;

    return out.str();
}

void Rational::double2Rational(double f, Range nRange, Range dRange,
                    Rational& lower, Rational& upper)
{
    Rational bestLower(nRange.lower(), dRange.upper());
    Rational bestUpper(nRange.upper(), dRange.lower());

    // Search for a better solution
    for (uint32_t d = dRange.lower(); d <= dRange.upper(); d++) {
        Rational val(d * f, d);  // Lower, because double to int cast truncates

        if ((val.numerator() < nRange.lower())
            || (val.numerator() > nRange.upper())) { continue; }

        if (((double) val > (double) bestLower) && ((double) val <= f)) {
            bestLower = val;
        } 

        val.setNumerator(val.numerator() + 1);
        if (val.numerator() > nRange.upper()) { continue; }

        if (((double) val < (double) bestUpper) && ((double) val >= f)) {
            bestUpper = val;
        }
    }

    lower = bestLower;
    upper = bestUpper;
}

// Local functions

// Num Overlays
// Given a list of rectangles, determine how many HWC will commit to render
uint32_t numOverlays(list<Rectangle>& rectList)
{
    hwc_display_contents_1_t *hwcList;
    list<sp<GraphicBuffer> > buffers;

    hwcList = hwcTestCreateLayerList(rectList.size());
    if (hwcList == NULL) {
        testPrintE("numOverlays create hwcList failed");
        exit(30);
    }

    hwc_layer_1_t *layer = &hwcList->hwLayers[0];
    for (std::list<Rectangle>::iterator it = rectList.begin();
         it != rectList.end(); ++it, ++layer) {
        // Allocate the texture for the source frame
        // and push it onto the buffers list, so that it
        // stays in scope until a return from this function.
        sp<GraphicBuffer> texture;
        texture  = new GraphicBuffer(it->sourceDim.width(),
                                     it->sourceDim.height(),
                                     it->format, texUsage);
        buffers.push_back(texture);

        layer->handle = texture->handle;
        layer->blending = it->blend;
        layer->transform = it->transform;
        layer->sourceCrop = it->sourceCrop;
        layer->displayFrame = it->displayFrame;

        layer->visibleRegionScreen.numRects = 1;
        layer->visibleRegionScreen.rects = &layer->displayFrame;
    }

    // Perform prepare operation
    if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(hwcList); }
    hwcDevice->prepare(hwcDevice, 1, &hwcList);
    if (verbose) {
        testPrintI("Post Prepare:");
        hwcTestDisplayListPrepareModifiable(hwcList);
    }

    // Count the number of overlays
    uint32_t total = 0;
    for (unsigned int n1 = 0; n1 < hwcList->numHwLayers; n1++) {
        if (hwcList->hwLayers[n1].compositionType == HWC_OVERLAY) {
            total++;
        }
    }

    // Free the layer list and graphic buffers
    hwcTestFreeLayerList(hwcList);

    return total;
}

string transformList2str(const list<uint32_t>& transformList)
{
    ostringstream out;

    for (list<uint32_t>::const_iterator it = transformList.begin();
         it != transformList.end(); ++it) {
        uint32_t id = *it;

        if (it != transformList.begin()) {
            out << ", ";
        }
        out << id;

        for (unsigned int idx = 0; idx < NUMA(transformType); idx++) {
            if (id == transformType[idx].id) {
                out << " (" << transformType[idx].desc << ')';
                break;
            }
        }
    }

    return out.str();
}

string blendList2str(const list<uint32_t>& blendList)
{
    ostringstream out;

    for (list<uint32_t>::const_iterator it = blendList.begin();
         it != blendList.end(); ++it) {
        uint32_t id = *it;

        if (it != blendList.begin()) {
            out << ", ";
        }
        out << id;

        for (unsigned int idx = 0; idx < NUMA(blendType); idx++) {
            if (id == blendType[idx].id) {
                out << " (" << blendType[idx].desc << ')';
                break;
            }
        }
    }

    return out.str();
}

void init(void)
{
    srand48(0);

    hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height);

    hwcTestOpenHwc(&hwcDevice);
}

void printFormatHeadings(size_t indent)
{
    for (size_t row = 0; row <= maxHeadingLen; row++) {
        ostringstream line;
        for(vector<string>::iterator it = formats.begin();
            it != formats.end(); ++it) {
            if ((maxHeadingLen - row) <= it->length()) {
                if (row != maxHeadingLen) {
                    char ch = (*it)[it->length() - (maxHeadingLen - row)];
                    line << ' ' << setw(printFieldWidth) << ch;
                } else {
                    line << ' ' << string(printFieldWidth, '-');
                }
            } else {
               line << ' ' << setw(printFieldWidth) << "";
            }
        }
        testPrintI("%*s%s", indent + maxHeadingLen, "",
                   line.str().c_str());
    }
}

void printOverlapLine(size_t indent, const string formatStr,
                        const vector<uint32_t>& results)
{
    ostringstream line;

    line << setw(indent + maxHeadingLen - formatStr.length()) << "";

    line << formatStr;

    for (vector<uint32_t>::const_iterator it = results.begin();
         it != results.end(); ++it) {
        line << ' ' << setw(printFieldWidth) << *it;
    }

    testPrintI("%s", line.str().c_str());
}

void printSyntax(const char *cmd)
{
    testPrintE("  %s [options] [graphicFormat] ...",
               cmd);
    testPrintE("    options:");
    testPrintE("      -s [width, height] - start dimension");
    testPrintE("      -v - Verbose");
    testPrintE("");
    testPrintE("    graphic formats:");
    for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) {
        testPrintE("      %s", hwcTestGraphicFormat[n1].desc);
    }
}
