/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "PictureRenderingFlags.h"

#include "CopyTilesRenderer.h"
#include "PictureRenderer.h"
#include "picture_utils.h"
#include "SkCommandLineFlags.h"
#include "SkData.h"
#include "SkImage.h"
#include "SkImageDecoder.h"
#include "SkString.h"

// Alphabetized list of flags used by this file or bench_ and render_pictures.
DEFINE_string(bbh, "none", "bbhType [width height]: Set the bounding box hierarchy type to "
              "be used. Accepted values are: none, rtree, grid. "
              "Not compatible with --pipe. With value "
              "'grid', width and height must be specified. 'grid' can "
              "only be used with modes tile, record, and "
              "playbackCreation.");


#if SK_SUPPORT_GPU
static const char kGpuAPINameGL[] = "gl";
static const char kGpuAPINameGLES[] = "gles";
#define GPU_CONFIG_STRING "|gpu|msaa4|msaa16|nvprmsaa4|nvprmsaa16|gpudft"
#else
#define GPU_CONFIG_STRING ""
#endif
#if SK_ANGLE
#define ANGLE_CONFIG_STRING "|angle"
#else
#define ANGLE_CONFIG_STRING ""
#endif
#if SK_MESA
#define MESA_CONFIG_STRING "|mesa"
#else
#define MESA_CONFIG_STRING ""
#endif

// Although this config does not support all the same options as gm, the names should be kept
// consistent.
DEFINE_string(config, "8888", "["
              "8888" GPU_CONFIG_STRING ANGLE_CONFIG_STRING MESA_CONFIG_STRING
              "]: Use the corresponding config.");

DEFINE_bool(deferImageDecoding, false, "Defer decoding until drawing images. "
            "Has no effect if the provided skp does not have its images encoded.");
DEFINE_string(mode, "simple", "Run in the corresponding mode:\n"
              "simple: Simple rendering.\n"
              "tile width height: Use tiles with the given dimensions or percentages.\n"
              "pow2tile minWidth height: Use tiles with widths that are all a power\n"
              "\tof two such that they minimize the amount of wasted tile space.\n"
              "\tminWidth must be a power of two.\n"
              "copyTile width height: Draw the picture, then copy into tiles. If the\n"
              "\tpicture is large enough, it is broken into larger tiles to avoid\n"
              "\tcreating a large canvas.\n"
// TODO: If bench_pictures and render_pictures were two separate targets, we could use build flags
// to determine which modes to display.
              "record: (Only in bench_pictures) Time recording from a picture to a new\n"
              "\tpicture.\n"
              "playbackCreation: (Only in bench_pictures) Time creation of the \n"
              "\tSkPicturePlayback.\n"
              "rerecord: (Only in render_pictures) Record the picture as a new skp,\n"
              "\twith the bitmaps PNG encoded.\n");
DEFINE_bool(pipe, false, "Use SkGPipe rendering. Currently incompatible with \"mode\".");
DEFINE_string2(readPath, r, "", "skp files or directories of skp files to process.");
DEFINE_double(scale, 1, "Set the scale factor.");
DEFINE_string(tiles, "", "Used with --mode copyTile to specify number of tiles per larger tile "
              "in the x and y directions.");
DEFINE_string(viewport, "", "width height: Set the viewport.");
#if SK_SUPPORT_GPU
DEFINE_string(gpuAPI, "", "Force use of specific gpu API.  Using \"gl\" "
              "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
              "Defaults to empty string, which selects the API native to the "
              "system.");
DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to "
                                          "software path rendering.");
#endif

sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) {
    error.reset();

    bool useTiles = false;
    const char* widthString = NULL;
    const char* heightString = NULL;
    bool isPowerOf2Mode = false;
    bool isCopyMode = false;
    const char* mode = NULL;
    bool gridSupported = false;

#if SK_SUPPORT_GPU
    GrContext::Options grContextOpts;
    grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks;
  #define RENDERER_ARGS (grContextOpts)
#else
  #define RENDERER_ARGS ()
#endif

    SkAutoTUnref<sk_tools::PictureRenderer> renderer;
    if (FLAGS_mode.count() >= 1) {
        mode = FLAGS_mode[0];
        if (0 == strcmp(mode, "record")) {
            renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS));
            gridSupported = true;
        } else if (0 == strcmp(mode, "tile") || 0 == strcmp(mode, "pow2tile")
                   || 0 == strcmp(mode, "copyTile")) {
            useTiles = true;

            if (0 == strcmp(mode, "pow2tile")) {
                isPowerOf2Mode = true;
            } else if (0 == strcmp(mode, "copyTile")) {
                isCopyMode = true;
            } else {
                gridSupported = true;
            }

            if (FLAGS_mode.count() < 2) {
                error.printf("Missing width for --mode %s\n", mode);
                return NULL;
            }

            widthString = FLAGS_mode[1];
            if (FLAGS_mode.count() < 3) {
                error.printf("Missing height for --mode %s\n", mode);
                return NULL;
            }

            heightString = FLAGS_mode[2];
        } else if (0 == strcmp(mode, "playbackCreation") && kBench_PictureTool == tool) {
            renderer.reset(SkNEW_ARGS(sk_tools::PlaybackCreationRenderer, RENDERER_ARGS));
            gridSupported = true;
        // undocumented
        } else if (0 == strcmp(mode, "gatherPixelRefs") && kBench_PictureTool == tool) {
#if SK_SUPPORT_GPU
            renderer.reset(sk_tools::CreateGatherPixelRefsRenderer(grContextOpts));
#else
            renderer.reset(sk_tools::CreateGatherPixelRefsRenderer());
#endif
        } else if (0 == strcmp(mode, "rerecord") && kRender_PictureTool == tool) {
            renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS));
        // Allow 'mode' to be set to 'simple', but do not create a renderer, so we can
        // ensure that pipe does not override a mode besides simple. The renderer will
        // be created below.
        } else if (0 == strcmp(mode, "simple")) {
            gridSupported = true;
        } else {
            error.printf("%s is not a valid mode for --mode\n", mode);
            return NULL;
        }
    }

    if (useTiles) {
        SkASSERT(NULL == renderer);
        SkAutoTUnref<sk_tools::TiledPictureRenderer> tiledRenderer;
        if (isCopyMode) {
            int xTiles = -1;
            int yTiles = -1;
            if (FLAGS_tiles.count() > 0) {
                if (FLAGS_tiles.count() != 2) {
                    error.printf("--tiles requires an x value and a y value.\n");
                    return NULL;
                }
                xTiles = atoi(FLAGS_tiles[0]);
                yTiles = atoi(FLAGS_tiles[1]);
            }

            int x, y;
            if (xTiles != -1 && yTiles != -1) {
                x = xTiles;
                y = yTiles;
                if (x <= 0 || y <= 0) {
                    error.printf("--tiles must be given values > 0\n");
                    return NULL;
                }
            } else {
                x = y = 4;
            }
#if SK_SUPPORT_GPU
            tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (grContextOpts, x, y)));
#else
            tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (x, y)));
#endif
        } else {
            tiledRenderer.reset(SkNEW_ARGS(sk_tools::TiledPictureRenderer, RENDERER_ARGS));
        }

        if (isPowerOf2Mode) {
            int minWidth = atoi(widthString);
            if (!SkIsPow2(minWidth) || minWidth < 0) {
                SkString err;
                error.printf("-mode %s must be given a width"
                             " value that is a power of two\n", mode);
                return NULL;
            }
            tiledRenderer->setTileMinPowerOf2Width(minWidth);
        } else if (sk_tools::is_percentage(widthString)) {
            if (isCopyMode) {
                error.printf("--mode %s does not support percentages.\n", mode);
                return NULL;
            }
            tiledRenderer->setTileWidthPercentage(atof(widthString));
            if (!(tiledRenderer->getTileWidthPercentage() > 0)) {
                error.printf("--mode %s must be given a width percentage > 0\n", mode);
                return NULL;
            }
        } else {
            tiledRenderer->setTileWidth(atoi(widthString));
            if (!(tiledRenderer->getTileWidth() > 0)) {
                error.printf("--mode %s must be given a width > 0\n", mode);
                return NULL;
            }
        }

        if (sk_tools::is_percentage(heightString)) {
            if (isCopyMode) {
                error.printf("--mode %s does not support percentages.\n", mode);
                return NULL;
            }
            tiledRenderer->setTileHeightPercentage(atof(heightString));
            if (!(tiledRenderer->getTileHeightPercentage() > 0)) {
                error.printf("--mode %s must be given a height percentage > 0\n", mode);
                return NULL;
            }
        } else {
            tiledRenderer->setTileHeight(atoi(heightString));
            if (!(tiledRenderer->getTileHeight() > 0)) {
                SkString err;
                error.printf("--mode %s must be given a height > 0\n", mode);
                return NULL;
            }
        }

        renderer.reset(tiledRenderer.detach());
        if (FLAGS_pipe) {
            error.printf("Pipe rendering is currently not compatible with tiling.\n"
                         "Turning off pipe.\n");
        }

    } else { // useTiles
        if (FLAGS_pipe) {
            if (renderer != NULL) {
                error.printf("Pipe is incompatible with other modes.\n");
                return NULL;
            }
            renderer.reset(SkNEW_ARGS(sk_tools::PipePictureRenderer, RENDERER_ARGS));
        }
    }

    if (NULL == renderer) {
        renderer.reset(SkNEW_ARGS(sk_tools::SimplePictureRenderer, RENDERER_ARGS));
    }

    if (FLAGS_viewport.count() > 0) {
        if (FLAGS_viewport.count() != 2) {
            error.printf("--viewport requires a width and a height.\n");
            return NULL;
        }
        SkISize viewport;
        viewport.fWidth = atoi(FLAGS_viewport[0]);
        viewport.fHeight = atoi(FLAGS_viewport[1]);
        renderer->setViewport(viewport);
    }

    sk_tools::PictureRenderer::SkDeviceTypes deviceType =
        sk_tools::PictureRenderer::kBitmap_DeviceType;
#if SK_SUPPORT_GPU
    GrGLStandard gpuAPI = kNone_GrGLStandard;
    if (1 == FLAGS_gpuAPI.count()) {
        if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
            gpuAPI = kGL_GrGLStandard;
        } else if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
            gpuAPI = kGLES_GrGLStandard;
        } else {
            error.printf("--gpuAPI invalid api value.\n");
            return NULL;
        }
    } else if (FLAGS_gpuAPI.count() > 1) {
        error.printf("--gpuAPI invalid api value.\n");
        return NULL;
    }

    int sampleCount = 0;
    bool useDFText = false;
#endif
    if (FLAGS_config.count() > 0) {
        if (0 == strcmp(FLAGS_config[0], "8888")) {
            deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
        }
#if SK_SUPPORT_GPU
        else if (0 == strcmp(FLAGS_config[0], "gpu")) {
            deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
        }
        else if (0 == strcmp(FLAGS_config[0], "msaa4")) {
            deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
            sampleCount = 4;
        }
        else if (0 == strcmp(FLAGS_config[0], "msaa16")) {
            deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
            sampleCount = 16;
        }
        else if (0 == strcmp(FLAGS_config[0], "nvprmsaa4")) {
            deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
            sampleCount = 4;
        }
        else if (0 == strcmp(FLAGS_config[0], "nvprmsaa16")) {
            deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
            sampleCount = 16;
        }
        else if (0 == strcmp(FLAGS_config[0], "gpudft")) {
            deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
            useDFText = true;
        }
#if SK_ANGLE
        else if (0 == strcmp(FLAGS_config[0], "angle")) {
            deviceType = sk_tools::PictureRenderer::kAngle_DeviceType;
        }
#endif
#if SK_MESA
        else if (0 == strcmp(FLAGS_config[0], "mesa")) {
            deviceType = sk_tools::PictureRenderer::kMesa_DeviceType;
        }
#endif
#endif
        else {
            error.printf("%s is not a valid mode for --config\n", FLAGS_config[0]);
            return NULL;
        }
#if SK_SUPPORT_GPU
        if (!renderer->setDeviceType(deviceType, gpuAPI)) {
#else
        if (!renderer->setDeviceType(deviceType)) {
#endif
            error.printf("Could not create backend for --config %s\n", FLAGS_config[0]);
            return NULL;
        }
#if SK_SUPPORT_GPU
        renderer->setSampleCount(sampleCount);
        renderer->setUseDFText(useDFText);
#endif
    }


    sk_tools::PictureRenderer::BBoxHierarchyType bbhType
            = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
    if (FLAGS_bbh.count() > 0) {
        const char* type = FLAGS_bbh[0];
        if (0 == strcmp(type, "none")) {
            bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
        } else if (0 == strcmp(type, "rtree")) {
            bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
        } else if (0 == strcmp(type, "grid")) {
            if (!gridSupported) {
                error.printf("'--bbh grid' is not compatible with --mode=%s.\n", mode);
                return NULL;
            }
            bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType;
            if (FLAGS_bbh.count() != 3) {
                error.printf("--bbh grid requires a width and a height.\n");
                return NULL;
            }
            int gridWidth = atoi(FLAGS_bbh[1]);
            int gridHeight = atoi(FLAGS_bbh[2]);
            renderer->setGridSize(gridWidth, gridHeight);

        } else {
            error.printf("%s is not a valid value for --bbhType\n", type);
            return NULL;
        }
        if (FLAGS_pipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) {
            error.printf("--pipe and --bbh cannot be used together\n");
            return NULL;
        }
    }
    renderer->setBBoxHierarchyType(bbhType);
    renderer->setScaleFactor(SkDoubleToScalar(FLAGS_scale));

    return renderer.detach();
}
