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

#include "tools/flags/CommonFlagsGanesh.h"

#include "include/core/SkExecutor.h"
#include "include/gpu/ganesh/GrContextOptions.h"
#include "src/core/SkExecutors.h"

// Defined in CommonFlagsConfig
DECLARE_int(gpuThreads)
DECLARE_int(internalSamples)

namespace CommonFlags {

static DEFINE_bool(cachePathMasks, true,
                   "Allows path mask textures to be cached in GPU configs.");
static DEFINE_bool(failFlushTimeCallbacks, false,
                   "Causes all flush-time callbacks to fail.");
static DEFINE_bool(allPathsVolatile, false,
                   "Causes all GPU paths to be processed as if 'setIsVolatile' had been called.");

static DEFINE_string(pr, "",
              "Set of enabled gpu path renderers. Defined as a list of: "
              "[~]none [~]dashline [~]aahairline [~]aaconvex [~]aalinearizing [~]small [~]tri "
              "[~]atlas [~]tess [~]all");

static DEFINE_int(maxAtlasSize, -1,
        "Maximum width and height of internal texture atlases, or default value if negative.");

static DEFINE_bool(disableDriverCorrectnessWorkarounds, false,
                   "Disables all GPU driver correctness workarounds");

static DEFINE_bool(dontReduceOpsTaskSplitting, false,
                   "Don't reorder tasks to reduce render passes");

static DEFINE_int(gpuResourceCacheLimit, -1,
                  "Maximum number of bytes to use for budgeted GPU resources. "
                  "Default is -1, which means GrResourceCache::kDefaultMaxSize.");

static DEFINE_bool(allowMSAAOnNewIntel, false,
                   "Allows MSAA to be enabled on newer intel GPUs.");

static GpuPathRenderers get_named_pathrenderers_flags(const char* name) {
    if (!strcmp(name, "none")) {
        return GpuPathRenderers::kNone;
    } else if (!strcmp(name, "dashline")) {
        return GpuPathRenderers::kDashLine;
    } else if (!strcmp(name, "aahairline")) {
        return GpuPathRenderers::kAAHairline;
    } else if (!strcmp(name, "aaconvex")) {
        return GpuPathRenderers::kAAConvex;
    } else if (!strcmp(name, "aalinearizing")) {
        return GpuPathRenderers::kAALinearizing;
    } else if (!strcmp(name, "small")) {
        return GpuPathRenderers::kSmall;
    } else if (!strcmp(name, "tri")) {
        return GpuPathRenderers::kTriangulating;
    } else if (!strcmp(name, "atlas")) {
        return GpuPathRenderers::kAtlas;
    } else if (!strcmp(name, "tess")) {
        return GpuPathRenderers::kTessellation;
    } else if (!strcmp(name, "default")) {
        return GpuPathRenderers::kDefault;
    }
    SK_ABORT("error: unknown named path renderer \"%s\"", name);
}

static GpuPathRenderers collect_gpu_path_renderers_from_flags() {
    if (FLAGS_pr.isEmpty()) {
        return GpuPathRenderers::kDefault;
    }

    GpuPathRenderers gpuPathRenderers = ('~' == FLAGS_pr[0][0])
            ? GpuPathRenderers::kDefault
            : GpuPathRenderers::kNone;

    for (int i = 0; i < FLAGS_pr.size(); ++i) {
        const char* name = FLAGS_pr[i];
        if (name[0] == '~') {
            gpuPathRenderers &= ~get_named_pathrenderers_flags(&name[1]);
        } else {
            gpuPathRenderers |= get_named_pathrenderers_flags(name);
        }
    }
    return gpuPathRenderers;
}

void SetCtxOptions(GrContextOptions* ctxOptions) {
    static std::unique_ptr<SkExecutor> gGpuExecutor = (0 != FLAGS_gpuThreads)
        ? SkExecutors::MakeFIFOThreadPool(FLAGS_gpuThreads)
        : nullptr;

    ctxOptions->fExecutor                            = gGpuExecutor.get();
    ctxOptions->fAllowPathMaskCaching                = FLAGS_cachePathMasks;
    ctxOptions->fFailFlushTimeCallbacks              = FLAGS_failFlushTimeCallbacks;
    ctxOptions->fAllPathsVolatile                    = FLAGS_allPathsVolatile;
    ctxOptions->fGpuPathRenderers                    = collect_gpu_path_renderers_from_flags();
    ctxOptions->fDisableDriverCorrectnessWorkarounds = FLAGS_disableDriverCorrectnessWorkarounds;
    ctxOptions->fResourceCacheLimitOverride          = FLAGS_gpuResourceCacheLimit;

    if (FLAGS_internalSamples >= 0) {
        ctxOptions->fInternalMultisampleCount = FLAGS_internalSamples;
    }
    if (FLAGS_maxAtlasSize >= 0) {
        ctxOptions->fMaxTextureAtlasSize = FLAGS_maxAtlasSize;
    }

    if (FLAGS_dontReduceOpsTaskSplitting) {
        ctxOptions->fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo;
    } else {
        ctxOptions->fReduceOpsTaskSplitting = GrContextOptions::Enable::kYes;
    }
    ctxOptions->fAllowMSAAOnNewIntel = FLAGS_allowMSAAOnNewIntel;
}

}  // namespace CommonFlags
