/*
 * Copyright (C) 2010 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 stress test
 *
 * Performs a pseudo-random (prandom) sequence of operations to the
 * Hardware Composer (HWC), for a specified number of passes or for
 * a specified period of time.  By default the period of time is FLT_MAX,
 * so that the number of passes will take precedence.
 *
 * The passes are grouped together, where (pass / passesPerGroup) specifies
 * which group a particular pass is in.  This causes every passesPerGroup
 * worth of sequential passes to be within the same group.  Computationally
 * intensive operations are performed just once at the beginning of a group
 * of passes and then used by all the passes in that group.  This is done
 * so as to increase both the average and peak rate of graphic operations,
 * by moving computationally intensive operations to the beginning of a group.
 * In particular, at the start of each group of passes a set of
 * graphic buffers are created, then used by the first and remaining
 * passes of that group of passes.
 *
 * The per-group initialization of the graphic buffers is performed
 * by a function called initFrames.  This function creates an array
 * of smart pointers to the graphic buffers, in the form of a vector
 * of vectors.  The array is accessed in row major order, so each
 * row is a vector of smart pointers.  All the pointers of a single
 * row point to graphic buffers which use the same pixel format and
 * have the same dimension, although it is likely that each one is
 * filled with a different color.  This is done so that after doing
 * the first HWC prepare then set call, subsequent set calls can
 * be made with each of the layer handles changed to a different
 * graphic buffer within the same row.  Since the graphic buffers
 * in a particular row have the same pixel format and dimension,
 * additional HWC set calls can be made, without having to perform
 * an HWC prepare call.
 *
 * This test supports the following command-line options:
 *
 *   -v        Verbose
 *   -s num    Starting pass
 *   -e num    Ending pass
 *   -p num    Execute the single pass specified by num
 *   -n num    Number of set operations to perform after each prepare operation
 *   -t float  Maximum time in seconds to execute the test
 *   -d float  Delay in seconds performed after each set operation
 *   -D float  Delay in seconds performed after the last pass is executed
 *
 * Typically the test is executed for a large range of passes.  By default
 * passes 0 through 99999 (100,000 passes) are executed.  Although this test
 * does not validate the generated image, at times it is useful to reexecute
 * a particular pass and leave the displayed image on the screen for an
 * extended period of time.  This can be done either by setting the -s
 * and -e options to the desired pass, along with a large value for -D.
 * This can also be done via the -p option, again with a large value for
 * the -D options.
 *
 * So far this test only contains code to create graphic buffers with
 * a continuous solid color.  Although this test is unable to validate the
 * image produced, any image that contains other than rectangles of a solid
 * color are incorrect.  Note that the rectangles may use a transparent
 * color and have a blending operation that causes the color in overlapping
 * rectangles to be mixed.  In such cases the overlapping portions may have
 * a different color from the rest of the rectangle.
 */

#define LOG_TAG "hwcStressTest"

#include <algorithm>
#include <assert.h>
#include <cerrno>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <libgen.h>
#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/GraphicBuffer.h>

#include <utils/Log.h>
#include <testUtil.h>

#include <hardware/hwcomposer.h>

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

using namespace std;
using namespace android;

const float maxSizeRatio = 1.3;  // Graphic buffers can be upto this munch
                                 // larger than the default screen size
const unsigned int passesPerGroup = 10; // A group of passes all use the same
                                        // graphic buffers

// Ratios at which rare and frequent conditions should be produced
const float rareRatio = 0.1;
const float freqRatio = 0.9;

// Defaults for command-line options
const bool defaultVerbose = false;
const unsigned int defaultStartPass = 0;
const unsigned int defaultEndPass = 99999;
const unsigned int defaultPerPassNumSet = 10;
const float defaultPerSetDelay = 0.0; // Default delay after each set
                                      // operation.  Default delay of
                                      // zero used so as to perform the
                                      // the set operations as quickly
                                      // as possible.
const float defaultEndDelay = 2.0; // Default delay between completion of
                                   // final pass and restart of framework
const float defaultDuration = FLT_MAX; // A fairly long time, so that
                                       // range of passes will have
                                       // precedence

// Command-line option settings
static bool verbose = defaultVerbose;
static unsigned int startPass = defaultStartPass;
static unsigned int endPass = defaultEndPass;
static unsigned int numSet = defaultPerPassNumSet;
static float perSetDelay = defaultPerSetDelay;
static float endDelay = defaultEndDelay;
static float duration = defaultDuration;

// Command-line mutual exclusion detection flags.
// Corresponding flag set true once an option is used.
bool eFlag, sFlag, pFlag;

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

#define CMD_STOP_FRAMEWORK   "stop 2>&1"
#define CMD_START_FRAMEWORK  "start 2>&1"

#define NUMA(a) (sizeof(a) / sizeof((a)[0]))
#define MEMCLR(addr, size) do { \
        memset((addr), 0, (size)); \
    } while (0)

// File scope constants
const unsigned int blendingOps[] = {
    HWC_BLENDING_NONE,
    HWC_BLENDING_PREMULT,
    HWC_BLENDING_COVERAGE,
};
const unsigned int layerFlags[] = {
    HWC_SKIP_LAYER,
};
const vector<unsigned int> vecLayerFlags(layerFlags,
    layerFlags + NUMA(layerFlags));

const unsigned int transformFlags[] = {
    HWC_TRANSFORM_FLIP_H,
    HWC_TRANSFORM_FLIP_V,
    HWC_TRANSFORM_ROT_90,
    // ROT_180 & ROT_270 intentionally not listed, because they
    // they are formed from combinations of the flags already listed.
};
const vector<unsigned int> vecTransformFlags(transformFlags,
    transformFlags + NUMA(transformFlags));

// File scope 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 vector <vector <sp<GraphicBuffer> > > frames;

// File scope prototypes
void init(void);
void initFrames(unsigned int seed);
template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num);
template <class T> T vectorOr(const vector<T>& vec);

/*
 * Main
 *
 * Performs the following high-level sequence of operations:
 *
 *   1. Command-line parsing
 *
 *   2. Initialization
 *
 *   3. For each pass:
 *
 *        a. If pass is first pass or in a different group from the
 *           previous pass, initialize the array of graphic buffers.
 *
 *        b. Create a HWC list with room to specify a prandomly
 *           selected number of layers.
 *
 *        c. Select a subset of the rows from the graphic buffer array,
 *           such that there is a unique row to be used for each
 *           of the layers in the HWC list.
 *
 *        d. Prandomly fill in the HWC list with handles
 *           selected from any of the columns of the selected row.
 *
 *        e. Pass the populated list to the HWC prepare call.
 *
 *        f. Pass the populated list to the HWC set call.
 *
 *        g. If additional set calls are to be made, then for each
 *           additional set call, select a new set of handles and
 *           perform the set call.
 */
int
main(int argc, char *argv[])
{
    int rv, opt;
    char *chptr;
    unsigned int pass;
    char cmd[MAXCMD];
    struct timeval startTime, currentTime, delta;

    testSetLogCatTag(LOG_TAG);

    // Parse command line arguments
    while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) {
        switch (opt) {
          case 'd': // Delay after each set operation
            perSetDelay = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (perSetDelay < 0.0)) {
                testPrintE("Invalid command-line specified per pass delay of: "
                           "%s", optarg);
                exit(1);
            }
            break;

          case 'D': // End of test delay
                    // Delay between completion of final pass and restart
                    // of framework
            endDelay = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (endDelay < 0.0)) {
                testPrintE("Invalid command-line specified end of test delay "
                           "of: %s", optarg);
                exit(2);
            }
            break;

          case 't': // Duration
            duration = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (duration < 0.0)) {
                testPrintE("Invalid command-line specified duration of: %s",
                           optarg);
                exit(3);
            }
            break;

          case 'n': // Num set operations per pass
            numSet = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified num set per pass "
                           "of: %s", optarg);
                exit(4);
            }
            break;

          case 's': // Starting Pass
            sFlag = true;
            if (pFlag) {
                testPrintE("Invalid combination of command-line options.");
                testPrintE("  The -p option is mutually exclusive from the");
                testPrintE("  -s and -e options.");
                exit(5);
            }
            startPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified starting pass "
                           "of: %s", optarg);
                exit(6);
            }
            break;

          case 'e': // Ending Pass
            eFlag = true;
            if (pFlag) {
                testPrintE("Invalid combination of command-line options.");
                testPrintE("  The -p option is mutually exclusive from the");
                testPrintE("  -s and -e options.");
                exit(7);
            }
            endPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified ending pass "
                           "of: %s", optarg);
                exit(8);
            }
            break;

          case 'p': // Run a single specified pass
            pFlag = true;
            if (sFlag || eFlag) {
                testPrintE("Invalid combination of command-line options.");
                testPrintE("  The -p option is mutually exclusive from the");
                testPrintE("  -s and -e options.");
                exit(9);
            }
            startPass = endPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified pass of: %s",
                           optarg);
                exit(10);
            }
            break;

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

          case 'h': // Help
          case '?':
          default:
            testPrintE("  %s [options]", basename(argv[0]));
            testPrintE("    options:");
            testPrintE("      -p Execute specified pass");
            testPrintE("      -s Starting pass");
            testPrintE("      -e Ending pass");
            testPrintE("      -t Duration");
            testPrintE("      -d Delay after each set operation");
            testPrintE("      -D End of test delay");
            testPrintE("      -n Num set operations per pass");
            testPrintE("      -v Verbose");
            exit(((optopt == 0) || (optopt == '?')) ? 0 : 11);
        }
    }
    if (endPass < startPass) {
        testPrintE("Unexpected ending pass before starting pass");
        testPrintE("  startPass: %u endPass: %u", startPass, endPass);
        exit(12);
    }
    if (argc != optind) {
        testPrintE("Unexpected command-line postional argument");
        testPrintE("  %s [-s start_pass] [-e end_pass] [-t duration]",
            basename(argv[0]));
        exit(13);
    }
    testPrintI("duration: %g", duration);
    testPrintI("startPass: %u", startPass);
    testPrintI("endPass: %u", endPass);
    testPrintI("numSet: %u", numSet);

    // 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 - need means to query whether asyncronous stop
                    // framework operation has completed.  For now, just wait
                    // a long time.

    init();

    // For each pass
    gettimeofday(&startTime, NULL);
    for (pass = startPass; pass <= endPass; pass++) {
        // Stop if duration of work has already been performed
        gettimeofday(&currentTime, NULL);
        delta = tvDelta(&startTime, &currentTime);
        if (tv2double(&delta) > duration) { break; }

        // Regenerate a new set of test frames when this pass is
        // either the first pass or is in a different group then
        // the previous pass.  A group of passes are passes that
        // all have the same quotient when their pass number is
        // divided by passesPerGroup.
        if ((pass == startPass)
            || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) {
            initFrames(pass / passesPerGroup);
        }

        testPrintI("==== Starting pass: %u", pass);

        // Cause deterministic sequence of prandom numbers to be
        // generated for this pass.
        srand48(pass);

        hwc_display_contents_1_t *list;
        list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1);
        if (list == NULL) {
            testPrintE("hwcTestCreateLayerList failed");
            exit(20);
        }

        // Prandomly select a subset of frames to be used by this pass.
        vector <vector <sp<GraphicBuffer> > > selectedFrames;
        selectedFrames = vectorRandSelect(frames, list->numHwLayers);

        // Any transform tends to create a layer that the hardware
        // composer is unable to support and thus has to leave for
        // SurfaceFlinger.  Place heavy bias on specifying no transforms.
        bool noTransform = testRandFract() > rareRatio;

        for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
            unsigned int idx = testRandMod(selectedFrames[n1].size());
            sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
            hwc_layer_1_t *layer = &list->hwLayers[n1];
            layer->handle = gBuf->handle;

            layer->blending = blendingOps[testRandMod(NUMA(blendingOps))];
            layer->flags = (testRandFract() > rareRatio) ? 0
                : vectorOr(vectorRandSelect(vecLayerFlags,
                           testRandMod(vecLayerFlags.size() + 1)));
            layer->transform = (noTransform || testRandFract() > rareRatio) ? 0
                : vectorOr(vectorRandSelect(vecTransformFlags,
                           testRandMod(vecTransformFlags.size() + 1)));
            layer->sourceCrop.left = testRandMod(gBuf->getWidth());
            layer->sourceCrop.top = testRandMod(gBuf->getHeight());
            layer->sourceCrop.right = layer->sourceCrop.left
                + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1;
            layer->sourceCrop.bottom = layer->sourceCrop.top
                + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1;
            layer->displayFrame.left = testRandMod(width);
            layer->displayFrame.top = testRandMod(height);
            layer->displayFrame.right = layer->displayFrame.left
                + testRandMod(width - layer->displayFrame.left) + 1;
            layer->displayFrame.bottom = layer->displayFrame.top
                + testRandMod(height - layer->displayFrame.top) + 1;

            // Increase the frequency that a scale factor of 1.0 from
            // the sourceCrop to displayFrame occurs.  This is the
            // most common scale factor used by applications and would
            // be rarely produced by this stress test without this
            // logic.
            if (testRandFract() <= freqRatio) {
                // Only change to scale factor to 1.0 if both the
                // width and height will fit.
                int sourceWidth = layer->sourceCrop.right
                                  - layer->sourceCrop.left;
                int sourceHeight = layer->sourceCrop.bottom
                                   - layer->sourceCrop.top;
                if (((layer->displayFrame.left + sourceWidth) <= width)
                    && ((layer->displayFrame.top + sourceHeight) <= height)) {
                    layer->displayFrame.right = layer->displayFrame.left
                                                + sourceWidth;
                    layer->displayFrame.bottom = layer->displayFrame.top
                                                 + sourceHeight;
                }
            }

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

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

        // Turn off the geometry changed flag
        list->flags &= ~HWC_GEOMETRY_CHANGED;

        // Perform the set operation(s)
        if (verbose) {testPrintI("Set:"); }
        for (unsigned int n1 = 0; n1 < numSet; n1++) {
            if (verbose) { hwcTestDisplayListHandles(list); }
            list->dpy = dpy;
            list->sur = surface;
            hwcDevice->set(hwcDevice, 1, &list);

            // Prandomly select a new set of handles
            for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) {
                unsigned int idx = testRandMod(selectedFrames[n1].size());
                sp<GraphicBuffer> gBuf = selectedFrames[n1][idx];
                hwc_layer_1_t *layer = &list->hwLayers[n1];
                layer->handle = (native_handle_t *) gBuf->handle;
            }

            testDelay(perSetDelay);
        }

        hwcTestFreeLayerList(list);
        testPrintI("==== Completed pass: %u", pass);
    }

    testDelay(endDelay);

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

    testPrintI("Successfully completed %u passes", pass - startPass);

    return 0;
}

void init(void)
{
    srand48(0); // Defensively set pseudo random number generator.
                // Should not need to set this, because a stress test
                // sets the seed on each pass.  Defensively set it here
                // so that future code that uses pseudo random numbers
                // before the first pass will be deterministic.

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

    hwcTestOpenHwc(&hwcDevice);
}

/*
 * Initialize Frames
 *
 * Creates an array of graphic buffers, within the global variable
 * named frames.  The graphic buffers are contained within a vector of
 * vectors.  All the graphic buffers in a particular row are of the same
 * format and dimension.  Each graphic buffer is uniformly filled with a
 * prandomly selected color.  It is likely that each buffer, even
 * in the same row, will be filled with a unique color.
 */
void initFrames(unsigned int seed)
{
    int rv;
    const size_t maxRows = 5;
    const size_t minCols = 2;  // Need at least double buffering
    const size_t maxCols = 4;  // One more than triple buffering

    if (verbose) { testPrintI("initFrames seed: %u", seed); }
    srand48(seed);
    size_t rows = testRandMod(maxRows) + 1;

    frames.clear();
    frames.resize(rows);

    for (unsigned int row = 0; row < rows; row++) {
        // All frames within a row have to have the same format and
        // dimensions.  Width and height need to be >= 1.
        unsigned int formatIdx = testRandMod(NUMA(hwcTestGraphicFormat));
        const struct hwcTestGraphicFormat *formatPtr
            = &hwcTestGraphicFormat[formatIdx];
        int format = formatPtr->format;

        // Pick width and height, which must be >= 1 and the size
        // mod the wMod/hMod value must be equal to 0.
        size_t w = (width * maxSizeRatio) * testRandFract();
        size_t h = (height * maxSizeRatio) * testRandFract();
        w = max(size_t(1u), w);
        h = max(size_t(1u), h);
        if ((w % formatPtr->wMod) != 0) {
            w += formatPtr->wMod - (w % formatPtr->wMod);
        }
        if ((h % formatPtr->hMod) != 0) {
            h += formatPtr->hMod - (h % formatPtr->hMod);
        }
        if (verbose) {
            testPrintI("  frame %u width: %u height: %u format: %u %s",
                       row, w, h, format, hwcTestGraphicFormat2str(format));
        }

        size_t cols = testRandMod((maxCols + 1) - minCols) + minCols;
        frames[row].resize(cols);
        for (unsigned int col = 0; col < cols; col++) {
            ColorFract color(testRandFract(), testRandFract(), testRandFract());
            float alpha = testRandFract();

            frames[row][col] = new GraphicBuffer(w, h, format, texUsage);
            if ((rv = frames[row][col]->initCheck()) != NO_ERROR) {
                testPrintE("GraphicBuffer initCheck failed, rv: %i", rv);
                testPrintE("  frame %u width: %u height: %u format: %u %s",
                           row, w, h, format, hwcTestGraphicFormat2str(format));
                exit(80);
            }

            hwcTestFillColor(frames[row][col].get(), color, alpha);
            if (verbose) {
                testPrintI("    buf: %p handle: %p color: %s alpha: %f",
                           frames[row][col].get(), frames[row][col]->handle,
                           string(color).c_str(), alpha);
            }
        }
    }
}

/*
 * Vector Random Select
 *
 * Prandomly selects and returns num elements from vec.
 */
template <class T>
vector<T> vectorRandSelect(const vector<T>& vec, size_t num)
{
    vector<T> rv = vec;

    while (rv.size() > num) {
        rv.erase(rv.begin() + testRandMod(rv.size()));
    }

    return rv;
}

/*
 * Vector Or
 *
 * Or's togethen the values of each element of vec and returns the result.
 */
template <class T>
T vectorOr(const vector<T>& vec)
{
    T rv = 0;

    for (size_t n1 = 0; n1 < vec.size(); n1++) {
        rv |= vec[n1];
    }

    return rv;
}
