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

#ifndef GrGLSLVarying_DEFINED
#define GrGLSLVarying_DEFINED

#include "include/private/GrTypesPriv.h"
#include "src/core/SkTBlockList.h"
#include "src/gpu/GrShaderVar.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"

class GrGeometryProcessor;
class GrGLSLProgramBuilder;

#ifdef SK_DEBUG
static bool is_matrix(SkSLType type) {
    switch (type) {
        case SkSLType::kFloat2x2:
        case SkSLType::kFloat3x3:
        case SkSLType::kFloat4x4:
        case SkSLType::kHalf2x2:
        case SkSLType::kHalf3x3:
        case SkSLType::kHalf4x4:
            return true;
        default:
            return false;
    }
}
#endif

class GrGLSLVarying {
public:
    enum class Scope {
        kVertToFrag,
        kVertToGeo,
        kGeoToFrag
    };

    GrGLSLVarying() = default;
    GrGLSLVarying(SkSLType type, Scope scope = Scope::kVertToFrag)
        : fType(type)
        , fScope(scope) {
        // Metal doesn't support varying matrices, so we disallow them everywhere for consistency
        SkASSERT(!is_matrix(type));
    }

    void reset(SkSLType type, Scope scope = Scope::kVertToFrag) {
        // Metal doesn't support varying matrices, so we disallow them everywhere for consistency
        SkASSERT(!is_matrix(type));
        *this = GrGLSLVarying();
        fType = type;
        fScope = scope;
    }

    SkSLType type() const { return fType; }
    Scope scope() const { return fScope; }
    bool isInVertexShader() const { return Scope::kGeoToFrag != fScope; }
    bool isInFragmentShader() const { return Scope::kVertToGeo != fScope; }

    const char* vsOut() const { SkASSERT(this->isInVertexShader()); return fVsOut; }
    const char* fsIn() const { SkASSERT(this->isInFragmentShader()); return fFsIn; }

    GrShaderVar vsOutVar() const {
        SkASSERT(this->isInVertexShader());
        return GrShaderVar(this->vsOut(), fType, GrShaderVar::TypeModifier::Out);
    }

    GrShaderVar fsInVar() const {
        SkASSERT(this->isInFragmentShader());
        return GrShaderVar(this->fsIn(), fType, GrShaderVar::TypeModifier::In);
    }

private:
    SkSLType fType = SkSLType::kVoid;
    Scope fScope = Scope::kVertToFrag;
    const char* fVsOut = nullptr;
    const char* fFsIn = nullptr;

    friend class GrGLSLVaryingHandler;
};

static const int kVaryingsPerBlock = 8;

class GrGLSLVaryingHandler {
public:
    explicit GrGLSLVaryingHandler(GrGLSLProgramBuilder* program)
        : fVaryings(kVaryingsPerBlock)
        , fVertexInputs(kVaryingsPerBlock)
        , fVertexOutputs(kVaryingsPerBlock)
        , fFragInputs(kVaryingsPerBlock)
        , fFragOutputs(kVaryingsPerBlock)
        , fProgramBuilder(program)
        , fDefaultInterpolationModifier(nullptr) {}

    virtual ~GrGLSLVaryingHandler() {}

    /**
     * Notifies the varying handler that this shader will never emit geometry in perspective and
     * therefore does not require perspective-correct interpolation. When supported, this allows
     * varyings to use the "noperspective" keyword, which means the GPU can use cheaper math for
     * interpolation.
     */
    void setNoPerspective();

    enum class Interpolation {
        kInterpolated,
        kCanBeFlat, // Use "flat" if it will be faster.
        kMustBeFlat // Use "flat" even if it is known to be slow.
    };

    /**
     * addVarying allows fine grained control for setting up varyings between stages. Calling this
     * function will make sure all necessary decls are setup for the client. The client however is
     * responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an
     * attribute and pass it through to an output value in a fragment shader, use
     * addPassThroughAttribute.
     * TODO convert most uses of addVarying to addPassThroughAttribute
     */
    void addVarying(const char* name, GrGLSLVarying* varying,
                    Interpolation = Interpolation::kInterpolated);

    /**
     * The GP can use these calls to pass a vertex shader variable directly to 'output' in the
     * fragment shader. Though this adds code to vertex and fragment stages, 'output' is expected to
     * be defined in the fragment shader before the call is made.
     * TODO it might be nicer behavior to have a flag to declare output inside these calls
     */
    void addPassThroughAttribute(const GrShaderVar& vsVar,
                                 const char* output,
                                 Interpolation = Interpolation::kInterpolated);

    void emitAttributes(const GrGeometryProcessor&);

    // This should be called once all attributes and varyings have been added to the
    // GrGLSLVaryingHanlder and before getting/adding any of the declarations to the shaders.
    void finalize();

    void getVertexDecls(SkString* inputDecls, SkString* outputDecls) const;
    void getFragDecls(SkString* inputDecls, SkString* outputDecls) const;

protected:
    struct VaryingInfo {
        SkSLType         fType;
        bool             fIsFlat;
        SkString         fVsOut;
        GrShaderFlags    fVisibility;
    };

    typedef SkTBlockList<VaryingInfo> VaryingList;
    typedef SkTBlockList<GrShaderVar> VarArray;

    VaryingList    fVaryings;
    VarArray       fVertexInputs;
    VarArray       fVertexOutputs;
    VarArray       fFragInputs;
    VarArray       fFragOutputs;

    // This is not owned by the class
    GrGLSLProgramBuilder* fProgramBuilder;

private:
    void addAttribute(const GrShaderVar& var);

    virtual void onFinalize() = 0;

    // helper function for get*Decls
    void appendDecls(const VarArray& vars, SkString* out) const;

    const char* fDefaultInterpolationModifier;

    friend class GrGLSLProgramBuilder;
};

#endif
