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

#ifndef SKSL_PROGRAMSETTINGS
#define SKSL_PROGRAMSETTINGS

#include "include/private/SkSLDefines.h"
#include "include/sksl/SkSLVersion.h"
#include "src/sksl/SkSLProgramKind.h"

#include <vector>

namespace SkSL {

/**
 * Holds the compiler settings for a program.
 */
struct ProgramSettings {
    // If true, the destination fragment color can be read from sk_FragColor. It must be declared
    // inout. This is only supported in GLSL, when framebuffer-fetch is used.
    bool fFragColorIsInOut = false;
    // if true, all halfs are forced to be floats
    bool fForceHighPrecision = false;
    // if true, add -0.5 bias to LOD of all texture lookups
    bool fSharpenTextures = false;
    // If true, sk_FragCoord, the dFdy gradient, and sk_Clockwise won't be modified by the
    // rtFlip. Additionally, the 'fUseFlipRTUniform' boolean will be forced to false so no rtFlip
    // uniform will be emitted.
    bool fForceNoRTFlip = false;
    // if the program needs to create an RTFlip uniform, this is its offset in the uniform buffer
    int fRTFlipOffset = -1;
    // if the program needs to create an RTFlip uniform and is creating SPIR-V, this is the binding
    // and set number of the uniform buffer.
    int fRTFlipBinding = -1;
    int fRTFlipSet = -1;
    // If layout(set=S, binding=B) is not specified for a uniform, these values will be used.
    // At present, zero is always used by our backends.
    int fDefaultUniformSet = 0;
    int fDefaultUniformBinding = 0;
    // Enables the SkSL optimizer. Note that we never disable optimizations which are needed to
    // fully evaluate constant-expressions, like constant folding or constant-intrinsic evaluation.
    bool fOptimize = true;
    // (Requires fOptimize = true) Removes any uncalled functions other than main(). Note that a
    // function which starts out being used may end up being uncalled after optimization.
    bool fRemoveDeadFunctions = true;
    // (Requires fOptimize = true) Removes variables which are never used.
    bool fRemoveDeadVariables = true;
    // (Requires fOptimize = true) When greater than zero, enables the inliner. The threshold value
    // sets an upper limit on the acceptable amount of code growth from inlining.
    int fInlineThreshold = SkSL::kDefaultInlineThreshold;
    // If true, every function in the generated program will be given the `noinline` modifier.
    bool fForceNoInline = false;
    // If true, implicit conversions to lower precision numeric types are allowed (e.g., float to
    // half). These are always allowed when compiling Runtime Effects.
    bool fAllowNarrowingConversions = false;
    // If true, then Debug code will run SPIR-V output through the validator to ensure its
    // correctness
    bool fValidateSPIRV = true;
    // If true, any synthetic uniforms must use push constant syntax
    bool fUsePushConstants = false;
    // TODO(skia:11209) - Replace this with a "promised" capabilities?
    // Sets a maximum SkSL version. Compilation will fail if the program uses features that aren't
    // allowed at the requested version. For instance, a valid program must have fully-unrollable
    // `for` loops at version 100, but any loop structure is allowed at version 300.
    SkSL::Version fMaxVersionAllowed = SkSL::Version::k100;
    // If true, debug traces will contain the `trace_var` opcode. This opcode can cause the
    // generated code to contain a lot of extra computations, because we need to explicitly compute
    // every temporary value, even ones that would otherwise be optimized away entirely. The other
    // debug opcodes are much less invasive on the generated code.
    bool fAllowTraceVarInDebugTrace = true;
    // If true, SkSL will use a memory pool for all IR nodes when compiling a program. This is
    // usually a significant speed increase, but uses more memory, so it is a good idea for programs
    // that will be freed shortly after compilation. It can also be useful to disable this flag when
    // investigating memory corruption. (This controls behavior of the SkSL compiler, not the code
    // we generate.)
    bool fUseMemoryPool = true;
    // If true, VarDeclaration can be cloned for testing purposes. See VarDeclaration::clone for
    // more information.
    bool fAllowVarDeclarationCloneForTesting = false;
    // If true, SPIR-V codegen restricted to a subset supported by Dawn.
    // TODO(skia:13840, skia:14023): Remove this setting when Skia can use WGSL on Dawn.
    bool fSPIRVDawnCompatMode = false;
};

/**
 * All the configuration data for a given program.
 */
struct ProgramConfig {
    /** True if we are currently processing one of the built-in SkSL include modules. */
    bool fIsBuiltinCode;
    ProgramKind fKind;
    ProgramSettings fSettings;

    // When enforcesSkSLVersion() is true, this determines the available feature set that will be
    // enforced. This is set automatically when the `#version` directive is parsed.
    SkSL::Version fRequiredSkSLVersion = SkSL::Version::k100;

    bool enforcesSkSLVersion() const {
        return IsRuntimeEffect(fKind);
    }

    bool strictES2Mode() const {
        // TODO(skia:11209): Remove the first condition - so this is just based on #version.
        //                   Make it more generic (eg, isVersionLT) checking.
        return fSettings.fMaxVersionAllowed == Version::k100 &&
               fRequiredSkSLVersion == Version::k100 &&
               this->enforcesSkSLVersion();
    }

    const char* versionDescription() const {
        if (this->enforcesSkSLVersion()) {
            switch (fRequiredSkSLVersion) {
                case Version::k100: return "#version 100\n";
                case Version::k300: return "#version 300\n";
            }
        }
        return "";
    }

    static bool IsFragment(ProgramKind kind) {
        return kind == ProgramKind::kFragment ||
               kind == ProgramKind::kGraphiteFragment;
    }

    static bool IsVertex(ProgramKind kind) {
        return kind == ProgramKind::kVertex ||
               kind == ProgramKind::kGraphiteVertex;
    }

    static bool IsCompute(ProgramKind kind) {
        return kind == ProgramKind::kCompute;
    }

    static bool IsRuntimeEffect(ProgramKind kind) {
        return (kind == ProgramKind::kRuntimeColorFilter ||
                kind == ProgramKind::kRuntimeShader ||
                kind == ProgramKind::kRuntimeBlender ||
                kind == ProgramKind::kPrivateRuntimeColorFilter ||
                kind == ProgramKind::kPrivateRuntimeShader ||
                kind == ProgramKind::kPrivateRuntimeBlender ||
                kind == ProgramKind::kMeshVertex ||
                kind == ProgramKind::kMeshFragment);
    }

    static bool AllowsPrivateIdentifiers(ProgramKind kind) {
        return (kind != ProgramKind::kRuntimeColorFilter &&
                kind != ProgramKind::kRuntimeShader &&
                kind != ProgramKind::kRuntimeBlender &&
                kind != ProgramKind::kMeshVertex &&
                kind != ProgramKind::kMeshFragment);
    }
};

}  // namespace SkSL

#endif
