//
// Copyright 2002 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Program.h: Defines the gl::Program class. Implements GL program objects
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.

#ifndef LIBANGLE_PROGRAM_H_
#define LIBANGLE_PROGRAM_H_

#include <GLES2/gl2.h>
#include <GLSLANG/ShaderVars.h>

#include <array>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include "common/Optional.h"
#include "common/SimpleMutex.h"
#include "common/angleutils.h"
#include "common/hash_containers.h"
#include "common/mathutil.h"
#include "common/utilities.h"

#include "libANGLE/Constants.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/InfoLog.h"
#include "libANGLE/ProgramExecutable.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/angletypes.h"

namespace rx
{
class GLImplFactory;
class ProgramImpl;
class LinkSubTask;
struct TranslatedAttribute;
}  // namespace rx

namespace gl
{
class Buffer;
class BinaryInputStream;
class BinaryOutputStream;
struct Caps;
class Context;
struct Extensions;
class Framebuffer;
class ProgramExecutable;
class ShaderProgramManager;
class State;
struct UnusedUniform;
struct Version;

extern const char *const g_fakepath;

enum class LinkMismatchError
{
    // Shared
    NO_MISMATCH,
    TYPE_MISMATCH,
    ARRAYNESS_MISMATCH,
    ARRAY_SIZE_MISMATCH,
    PRECISION_MISMATCH,
    STRUCT_NAME_MISMATCH,
    FIELD_NUMBER_MISMATCH,
    FIELD_NAME_MISMATCH,

    // Varying specific
    INTERPOLATION_TYPE_MISMATCH,
    INVARIANCE_MISMATCH,

    // Uniform specific
    BINDING_MISMATCH,
    LOCATION_MISMATCH,
    OFFSET_MISMATCH,
    INSTANCE_NAME_MISMATCH,
    FORMAT_MISMATCH,

    // Interface block specific
    LAYOUT_QUALIFIER_MISMATCH,
    MATRIX_PACKING_MISMATCH,

    // I/O block specific
    FIELD_LOCATION_MISMATCH,
    FIELD_STRUCT_NAME_MISMATCH,
};

void LogLinkMismatch(InfoLog &infoLog,
                     const std::string &variableName,
                     const char *variableType,
                     LinkMismatchError linkError,
                     const std::string &mismatchedStructOrBlockFieldName,
                     ShaderType shaderType1,
                     ShaderType shaderType2);

bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock);

// Struct used for correlating uniforms/elements of uniform arrays to handles
ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
struct VariableLocation
{
    static constexpr unsigned int kUnused = GL_INVALID_INDEX;

    VariableLocation();
    VariableLocation(unsigned int arrayIndex, unsigned int index);

    // If used is false, it means this location is only used to fill an empty space in an array,
    // and there is no corresponding uniform variable for this location. It can also mean the
    // uniform was optimized out by the implementation.
    bool used() const { return (index != kUnused); }
    void markUnused() { index = kUnused; }
    void markIgnored() { ignored = true; }

    bool operator==(const VariableLocation &other) const
    {
        return arrayIndex == other.arrayIndex && index == other.index;
    }

    // "index" is an index of the variable. The variable contains the indices for other than the
    // innermost GLSL arrays.
    uint32_t index;

    // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
    uint32_t arrayIndex : 31;
    // If this location was bound to an unreferenced uniform.  Setting data on this uniform is a
    // no-op.
    uint32_t ignored : 1;
};
ANGLE_DISABLE_STRUCT_PADDING_WARNINGS

// Information about a variable binding.
// Currently used by CHROMIUM_path_rendering
struct BindingInfo
{
    // The type of binding, for example GL_FLOAT_VEC3.
    // This can be GL_NONE if the variable is optimized away.
    GLenum type;

    // This is the name of the variable in
    // the translated shader program. Note that
    // this can be empty in the case where the
    // variable has been optimized away.
    std::string name;

    // True if the binding is valid, otherwise false.
    bool valid;
};

struct ProgramBinding
{
    ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {}
    ProgramBinding(GLuint index) : location(index), aliased(false) {}

    GLuint location;
    // Whether another binding was set that may potentially alias this.
    bool aliased;
};

class ProgramBindings final : angle::NonCopyable
{
  public:
    ProgramBindings();
    ~ProgramBindings();

    void bindLocation(GLuint index, const std::string &name);
    int getBindingByName(const std::string &name) const;
    template <typename T>
    int getBinding(const T &variable) const;

    using const_iterator = angle::HashMap<std::string, GLuint>::const_iterator;
    const_iterator begin() const;
    const_iterator end() const;

    std::map<std::string, GLuint> getStableIterationMap() const;

  private:
    angle::HashMap<std::string, GLuint> mBindings;
};

enum class BindLocationPolicy
{
    AcceptIndexing,
    IgnoreIndexing,
};

// Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]")
class ProgramAliasedBindings final : angle::NonCopyable
{
  public:
    ProgramAliasedBindings();
    ~ProgramAliasedBindings();

    void bindLocation(GLuint index, const std::string &name, BindLocationPolicy policy);
    int getBindingByName(const std::string &name) const;
    int getBindingByLocation(GLuint location) const;
    template <typename T>
    int getBinding(const T &variable) const;

    using const_iterator = angle::HashMap<std::string, ProgramBinding>::const_iterator;
    const_iterator begin() const;
    const_iterator end() const;

    std::map<std::string, ProgramBinding> getStableIterationMap() const;

  private:
    angle::HashMap<std::string, ProgramBinding> mBindings;
};

class ProgramState final : angle::NonCopyable
{
  public:
    ProgramState(rx::GLImplFactory *factory);
    ~ProgramState();

    const std::string &getLabel();

    SharedCompiledShaderState getAttachedShader(ShaderType shaderType) const;
    const ShaderMap<SharedCompiledShaderState> &getAttachedShaders() const
    {
        return mAttachedShaders;
    }
    const std::vector<std::string> &getTransformFeedbackVaryingNames() const
    {
        return mTransformFeedbackVaryingNames;
    }
    GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }

    bool hasAnyAttachedShader() const;

    const ProgramBindings &getAttributeBindings() const { return mAttributeBindings; }
    const ProgramAliasedBindings &getUniformLocationBindings() const
    {
        return mUniformLocationBindings;
    }
    const ProgramAliasedBindings &getFragmentOutputLocations() const
    {
        return mFragmentOutputLocations;
    }
    const ProgramAliasedBindings &getFragmentOutputIndexes() const
    {
        return mFragmentOutputIndexes;
    }

    const ProgramExecutable &getExecutable() const
    {
        ASSERT(mExecutable);
        return *mExecutable;
    }
    ProgramExecutable &getExecutable()
    {
        ASSERT(mExecutable);
        return *mExecutable;
    }

    const SharedProgramExecutable &getSharedExecutable() const
    {
        ASSERT(mExecutable);
        return mExecutable;
    }

    const std::string &getLabel() const { return mLabel; }

    bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; }

    bool isSeparable() const { return mSeparable; }

    ShaderType getAttachedTransformFeedbackStage() const;

  private:
    friend class MemoryProgramCache;
    friend class Program;

    void updateActiveSamplers();
    void updateProgramInterfaceInputs();
    void updateProgramInterfaceOutputs();

    // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
    void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);

    std::string mLabel;

    ShaderMap<SharedCompileJob> mShaderCompileJobs;
    ShaderMap<SharedCompiledShaderState> mAttachedShaders;

    std::vector<std::string> mTransformFeedbackVaryingNames;
    GLenum mTransformFeedbackBufferMode;

    bool mBinaryRetrieveableHint;
    bool mSeparable;

    ProgramBindings mAttributeBindings;

    // Note that this has nothing to do with binding layout qualifiers that can be set for some
    // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
    ProgramAliasedBindings mUniformLocationBindings;

    // EXT_blend_func_extended
    ProgramAliasedBindings mFragmentOutputLocations;
    ProgramAliasedBindings mFragmentOutputIndexes;

    InfoLog mInfoLog;

    // The result of the link.  State that is not the link output should remain in ProgramState,
    // while the link output should be placed in ProgramExecutable.
    //
    // This is a shared_ptr because it can be "installed" in the context as part of the rendering
    // context.  Similarly, it can be installed in a program pipeline.  Once the executable is
    // installed, the actual Program should not be referenced; it may have been unsuccessfully
    // relinked and its executable in an unusable state.
    SharedProgramExecutable mExecutable;
};

struct ProgramVaryingRef
{
    const sh::ShaderVariable *get(ShaderType stage) const
    {
        ASSERT(stage == frontShaderStage || stage == backShaderStage);
        const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
        ASSERT(ref);
        return ref;
    }

    const sh::ShaderVariable *frontShader = nullptr;
    const sh::ShaderVariable *backShader  = nullptr;
    ShaderType frontShaderStage           = ShaderType::InvalidEnum;
    ShaderType backShaderStage            = ShaderType::InvalidEnum;
};

using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;

class Program final : public LabeledObject, public angle::Subject
{
  public:
    Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle);
    void onDestroy(const Context *context);

    ShaderProgramID id() const;

    angle::Result setLabel(const Context *context, const std::string &label) override;
    const std::string &getLabel() const override;

    ANGLE_INLINE rx::ProgramImpl *getImplementation() const
    {
        ASSERT(!mLinkingState);
        return mProgram;
    }

    void attachShader(const Context *context, Shader *shader);
    void detachShader(const Context *context, Shader *shader);
    int getAttachedShadersCount() const;

    Shader *getAttachedShader(ShaderType shaderType) const;

    void bindAttributeLocation(const Context *context, GLuint index, const char *name);
    void bindUniformLocation(const Context *context, UniformLocation location, const char *name);

    // EXT_blend_func_extended
    void bindFragmentOutputLocation(const Context *context, GLuint index, const char *name);
    void bindFragmentOutputIndex(const Context *context, GLuint index, const char *name);

    // KHR_parallel_shader_compile
    // Try to link the program asynchronously. As a result, background threads may be launched to
    // execute the linking tasks concurrently.
    angle::Result link(const Context *context, angle::JobResultExpectancy resultExpectancy);

    // Peek whether there is any running linking tasks.
    bool isLinking() const;
    bool hasLinkingState() const { return mLinkingState != nullptr; }

    bool isLinked() const
    {
        ASSERT(!mLinkingState);
        return mLinked;
    }
    bool isBinaryReady(const Context *context);
    ANGLE_INLINE void cacheProgramBinaryIfNecessary(const Context *context)
    {
        // This function helps ensure the program binary is cached, even if the backend waits for
        // post-link tasks without the knowledge of the front-end.
        if (!mIsBinaryCached && !mState.mExecutable->mBinaryRetrieveableHint &&
            mState.mExecutable->mPostLinkSubTasks.empty())
        {
            cacheProgramBinaryIfNotAlready(context);
        }
    }

    angle::Result setBinary(const Context *context,
                            GLenum binaryFormat,
                            const void *binary,
                            GLsizei length);
    angle::Result getBinary(Context *context,
                            GLenum *binaryFormat,
                            void *binary,
                            GLsizei bufSize,
                            GLsizei *length);
    GLint getBinaryLength(Context *context);
    void setBinaryRetrievableHint(bool retrievable);
    bool getBinaryRetrievableHint() const;

    angle::Result loadBinary(const Context *context,
                             const void *binary,
                             GLsizei length,
                             egl::CacheGetResult *resultOut);

    InfoLog &getInfoLog() { return mState.mInfoLog; }
    int getInfoLogLength() const;
    void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const;

    void setSeparable(const Context *context, bool separable);
    bool isSeparable() const { return mState.mSeparable; }

    void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const;

    void bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding);

    void setTransformFeedbackVaryings(const Context *context,
                                      GLsizei count,
                                      const GLchar *const *varyings,
                                      GLenum bufferMode);
    GLenum getTransformFeedbackBufferMode() const { return mState.mTransformFeedbackBufferMode; }

    ANGLE_INLINE void addRef() { mRefCount++; }

    ANGLE_INLINE void release(const Context *context)
    {
        mRefCount--;

        if (mRefCount == 0 && mDeleteStatus)
        {
            deleteSelf(context);
        }
    }

    unsigned int getRefCount() const;
    bool isInUse() const { return getRefCount() != 0; }
    void flagForDeletion();
    bool isFlaggedForDeletion() const;

    void validate(const Caps &caps);
    bool isValidated() const;

    const ProgramState &getState() const { return mState; }

    const ProgramBindings &getAttributeBindings() const { return mState.getAttributeBindings(); }
    const ProgramAliasedBindings &getUniformLocationBindings() const
    {
        return mState.getUniformLocationBindings();
    }
    const ProgramAliasedBindings &getFragmentOutputLocations() const
    {
        return mState.getFragmentOutputLocations();
    }
    const ProgramAliasedBindings &getFragmentOutputIndexes() const
    {
        return mState.getFragmentOutputIndexes();
    }

    // Try to resolve linking. Inlined to make sure its overhead is as low as possible.
    ANGLE_INLINE void resolveLink(const Context *context)
    {
        if (ANGLE_UNLIKELY(mLinkingState))
        {
            resolveLinkImpl(context);
        }
    }

    // Writes a program's binary to |mBinary|.
    angle::Result serialize(const Context *context);
    const angle::MemoryBuffer &getSerializedBinary() const { return mBinary; }

    rx::UniqueSerial serial() const { return mSerial; }

    const ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
    ProgramExecutable &getExecutable() { return mState.getExecutable(); }
    const SharedProgramExecutable &getSharedExecutable() const
    {
        return mState.getSharedExecutable();
    }

  private:
    class MainLinkLoadTask;
    class MainLoadTask;
    class MainLinkTask;
    class MainLinkLoadEvent;

    friend class ProgramPipeline;
    friend class MainLinkLoadTask;
    friend class MainLoadTask;
    friend class MainLinkTask;

    struct LinkingState;
    ~Program() override;

    // Loads program state according to the specified binary blob.  Returns true on success.
    bool deserialize(const Context *context, BinaryInputStream &stream);

    void unlink();
    void setupExecutableForLink(const Context *context);
    void syncExecutableOnSuccessfulLink();
    void deleteSelf(const Context *context);

    angle::Result linkJobImpl(const Caps &caps,
                              const Limitations &limitations,
                              const Version &clientVersion,
                              bool isWebGL,
                              LinkingVariables *linkingVariables,
                              ProgramLinkedResources *resources,
                              ProgramMergedVaryings *mergedVaryingsOut);

    void makeNewExecutable(const Context *context);

    bool linkValidateShaders();
    void linkShaders();
    bool linkAttributes(const Caps &caps, const Limitations &limitations, bool webglCompatibility);
    bool linkVaryings();

    bool linkUniforms(const Caps &caps,
                      const Version &clientVersion,
                      std::vector<UnusedUniform> *unusedUniformsOutOrNull,
                      GLuint *combinedImageUniformsOut);

    void updateLinkedShaderStages();

    // Block until linking is finished and resolve it.
    void resolveLinkImpl(const Context *context);
    // Block until post-link tasks are finished.
    void waitForPostLinkTasks(const Context *context);

    void postResolveLink(const Context *context);
    void cacheProgramBinaryIfNotAlready(const Context *context);

    void dumpProgramInfo(const Context *context) const;

    rx::UniqueSerial mSerial;
    ProgramState mState;
    rx::ProgramImpl *mProgram;

    bool mValidated;
    // Flag to indicate that the program can be deleted when no longer in use
    bool mDeleteStatus;
    // Whether the program binary is implicitly cached yet.  This is usually done in
    // |resolveLinkImpl|, but may be deferred in the presence of post-link tasks.  In that case,
    // |waitForPostLinkTasks| would cache the binary.  However, if the wait on the tasks is done by
    // the backend itself, this caching will not be done.  This flag is used to make sure the binary
    // is eventually cached at some point in the future.
    bool mIsBinaryCached;

    bool mLinked;
    std::unique_ptr<LinkingState> mLinkingState;

    egl::BlobCache::Key mProgramHash;

    unsigned int mRefCount;

    ShaderProgramManager *mResourceManager;
    const ShaderProgramID mHandle;

    // ProgramState::mAttachedShaders holds a reference to shaders' compiled state, which is all the
    // program and the backends require after link.  The actual shaders linked to the program are
    // stored here to support shader attach/detach and link without providing access to them in the
    // backends.
    ShaderMap<Shader *> mAttachedShaders;

    // A cache of the program binary, prepared by |serialize()|.  OpenGL requires the application to
    // query the length of the binary first (requiring a call to |serialize()|), and then get the
    // actual binary.  This cache ensures the second call does not need to call |serialize()| again.
    angle::MemoryBuffer mBinary;

    angle::SimpleMutex mHistogramMutex;
};
}  // namespace gl

#endif  // LIBANGLE_PROGRAM_H_
