//
// Copyright 2013 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.
//
// This class contains prototypes for representing GLES 3 Vertex Array Objects:
//
//   The buffer objects that are to be used by the vertex stage of the GL are collected
//   together to form a vertex array object. All state related to the definition of data used
//   by the vertex processor is encapsulated in a vertex array object.
//

#ifndef LIBANGLE_VERTEXARRAY_H_
#define LIBANGLE_VERTEXARRAY_H_

#include "common/Optional.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Observer.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/VertexAttribute.h"

#include <vector>

namespace rx
{
class GLImplFactory;
class VertexArrayImpl;
}  // namespace rx

namespace gl
{
class Buffer;

constexpr uint32_t kElementArrayBufferIndex = MAX_VERTEX_ATTRIBS;

class VertexArrayState final : angle::NonCopyable
{
  public:
    VertexArrayState(VertexArray *vertexArray, size_t maxAttribs, size_t maxBindings);
    ~VertexArrayState();

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

    Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
    size_t getMaxAttribs() const { return mVertexAttributes.size(); }
    size_t getMaxBindings() const { return mVertexBindings.size(); }
    const AttributesMask &getEnabledAttributesMask() const { return mEnabledAttributesMask; }
    const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
    const VertexAttribute &getVertexAttribute(size_t attribIndex) const
    {
        return mVertexAttributes[attribIndex];
    }
    const std::vector<VertexBinding> &getVertexBindings() const { return mVertexBindings; }
    const VertexBinding &getVertexBinding(size_t bindingIndex) const
    {
        return mVertexBindings[bindingIndex];
    }
    const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
    {
        return mVertexBindings[mVertexAttributes[attribIndex].bindingIndex];
    }
    size_t getBindingIndexFromAttribIndex(size_t attribIndex) const
    {
        return mVertexAttributes[attribIndex].bindingIndex;
    }

    void setAttribBinding(const Context *context, size_t attribIndex, GLuint newBindingIndex);

    // Extra validation performed on the Vertex Array.
    bool hasEnabledNullPointerClientArray() const;

    // Get all the attributes in an AttributesMask that are using the given binding.
    AttributesMask getBindingToAttributesMask(GLuint bindingIndex) const;

    ComponentTypeMask getVertexAttributesTypeMask() const { return mVertexAttributesTypeMask; }

    AttributesMask getClientMemoryAttribsMask() const { return mClientMemoryAttribsMask; }

    AttributesMask getNullPointerClientMemoryAttribsMask() const
    {
        return mNullPointerClientMemoryAttribsMask;
    }

    VertexArrayBufferBindingMask getBufferBindingMask() const { return mBufferBindingMask; }

    VertexArrayID id() const { return mId; }

    bool isDefault() const;

  private:
    void updateCachedMutableOrNonPersistentArrayBuffers(size_t index);

    friend class VertexArray;
    VertexArrayID mId;
    std::string mLabel;
    std::vector<VertexAttribute> mVertexAttributes;
    SubjectBindingPointer<Buffer> mElementArrayBuffer;
    std::vector<VertexBinding> mVertexBindings;
    AttributesMask mEnabledAttributesMask;
    ComponentTypeMask mVertexAttributesTypeMask;
    AttributesMask mLastSyncedEnabledAttributesMask;

    // Track which binding index has a buffer bound
    VertexArrayBufferBindingMask mBufferBindingMask;

    // This is a performance optimization for buffer binding. Allows element array buffer updates.
    friend class State;

    // From the GLES 3.1 spec:
    // When a generic attribute array is sourced from client memory, the vertex attribute binding
    // state is ignored. Thus we don't have to worry about binding state when using client memory
    // attribs.
    AttributesMask mClientMemoryAttribsMask;
    AttributesMask mNullPointerClientMemoryAttribsMask;

    // Used for validation cache. Indexed by attribute.
    AttributesMask mCachedMappedArrayBuffers;
    AttributesMask mCachedMutableOrImpersistentArrayBuffers;
    AttributesMask mCachedInvalidMappedArrayBuffer;
};

class VertexArrayBufferContentsObservers final : angle::NonCopyable
{
  public:
    VertexArrayBufferContentsObservers(VertexArray *vertexArray);
    void enableForBuffer(Buffer *buffer, uint32_t bufferIndex);
    void disableForBuffer(Buffer *buffer, uint32_t bufferIndex);
    bool any() const { return mBufferObserversBitMask.any(); }

  private:
    VertexArray *mVertexArray;
    // Bit is set when it is observing the buffer content change
    gl::AttributesMask mBufferObserversBitMask;
};

class VertexArray final : public angle::ObserverInterface,
                          public LabeledObject,
                          public angle::Subject
{
  public:
    // Dirty bits for VertexArrays use a hierarchical design. At the top level, each attribute
    // has a single dirty bit. Then an array of MAX_ATTRIBS dirty bits each has a dirty bit for
    // enabled/pointer/format/binding. Bindings are handled similarly. Note that because the
    // total number of dirty bits is 33, it will not be as fast on a 32-bit machine, which
    // can't support the advanced 64-bit scanning intrinsics. We could consider packing the
    // binding and attribute bits together if this becomes a problem.
    //
    // Special note on "DIRTY_ATTRIB_POINTER_BUFFER": this is a special case when the app
    // calls glVertexAttribPointer but only changes a VBO and/or offset binding. This allows
    // the Vulkan back-end to skip performing a pipeline change for performance.
    enum DirtyBitType
    {
        // This vertex array has lost buffer observation. Check against actual buffer storage is
        // required.
        DIRTY_BIT_LOST_OBSERVATION,

        DIRTY_BIT_ELEMENT_ARRAY_BUFFER,
        DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA,

        // Dirty bits for bindings.
        DIRTY_BIT_BINDING_0,
        DIRTY_BIT_BINDING_MAX = DIRTY_BIT_BINDING_0 + MAX_VERTEX_ATTRIB_BINDINGS,

        // We keep separate dirty bits for bound buffers whose data changed since last update.
        DIRTY_BIT_BUFFER_DATA_0   = DIRTY_BIT_BINDING_MAX,
        DIRTY_BIT_BUFFER_DATA_MAX = DIRTY_BIT_BUFFER_DATA_0 + MAX_VERTEX_ATTRIB_BINDINGS,

        // Dirty bits for attributes.
        DIRTY_BIT_ATTRIB_0   = DIRTY_BIT_BUFFER_DATA_MAX,
        DIRTY_BIT_ATTRIB_MAX = DIRTY_BIT_ATTRIB_0 + MAX_VERTEX_ATTRIBS,

        DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX,
        DIRTY_BIT_MAX     = DIRTY_BIT_UNKNOWN,
    };

    // We want to keep the number of dirty bits within 64 to keep iteration times fast.
    static_assert(DIRTY_BIT_MAX <= 64, "Too many vertex array dirty bits.");
    // The dirty bit processing has the logic to avoid redundant processing by removing other dirty
    // bits when it processes dirtyBits. This assertion ensures these dirty bit order matches what
    // VertexArrayVk::syncState expects.
    static_assert(DIRTY_BIT_BINDING_0 < DIRTY_BIT_BUFFER_DATA_0,
                  "BINDING dirty bits should come before DATA.");
    static_assert(DIRTY_BIT_BUFFER_DATA_0 < DIRTY_BIT_ATTRIB_0,
                  "DATA dirty bits should come before ATTRIB.");
    static_assert(DIRTY_BIT_LOST_OBSERVATION < DIRTY_BIT_BINDING_0,
                  "LOST_OBSERVATION dirty bits should come before BINDING.");

    enum DirtyAttribBitType
    {
        DIRTY_ATTRIB_ENABLED,
        DIRTY_ATTRIB_POINTER,
        DIRTY_ATTRIB_FORMAT,
        DIRTY_ATTRIB_BINDING,
        DIRTY_ATTRIB_POINTER_BUFFER,
        DIRTY_ATTRIB_MAX,
    };

    enum DirtyBindingBitType
    {
        DIRTY_BINDING_BUFFER,
        DIRTY_BINDING_DIVISOR,
        DIRTY_BINDING_STRIDE,
        DIRTY_BINDING_OFFSET,
        DIRTY_BINDING_MAX,
    };

    using DirtyBits                = angle::BitSet<DIRTY_BIT_MAX>;
    using DirtyAttribBits          = angle::BitSet<DIRTY_ATTRIB_MAX>;
    using DirtyBindingBits         = angle::BitSet<DIRTY_BINDING_MAX>;
    using DirtyAttribBitsArray     = std::array<DirtyAttribBits, MAX_VERTEX_ATTRIBS>;
    using DirtyBindingBitsArray    = std::array<DirtyBindingBits, MAX_VERTEX_ATTRIB_BINDINGS>;
    using DirtyObserverBindingBits = angle::BitSet<MAX_VERTEX_ATTRIB_BINDINGS>;

    VertexArray(rx::GLImplFactory *factory,
                VertexArrayID id,
                size_t maxAttribs,
                size_t maxAttribBindings);

    void onDestroy(const Context *context);

    VertexArrayID id() const { return mId; }

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

    const VertexBinding &getVertexBinding(size_t bindingIndex) const;
    const VertexAttribute &getVertexAttribute(size_t attribIndex) const;
    const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
    {
        return mState.getBindingFromAttribIndex(attribIndex);
    }

    // Returns true if the function finds and detaches a bound buffer.
    bool detachBuffer(const Context *context, BufferID bufferID);

    void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
    void enableAttribute(size_t attribIndex, bool enabledState);

    void setVertexAttribPointer(const Context *context,
                                size_t attribIndex,
                                Buffer *boundBuffer,
                                GLint size,
                                VertexAttribType type,
                                bool normalized,
                                GLsizei stride,
                                const void *pointer);

    void setVertexAttribIPointer(const Context *context,
                                 size_t attribIndex,
                                 Buffer *boundBuffer,
                                 GLint size,
                                 VertexAttribType type,
                                 GLsizei stride,
                                 const void *pointer);

    void setVertexAttribFormat(size_t attribIndex,
                               GLint size,
                               VertexAttribType type,
                               bool normalized,
                               bool pureInteger,
                               GLuint relativeOffset);
    void bindVertexBuffer(const Context *context,
                          size_t bindingIndex,
                          Buffer *boundBuffer,
                          GLintptr offset,
                          GLsizei stride);
    void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex);
    void setVertexBindingDivisor(const Context *context, size_t bindingIndex, GLuint divisor);

    Buffer *getElementArrayBuffer() const { return mState.getElementArrayBuffer(); }
    size_t getMaxAttribs() const { return mState.getMaxAttribs(); }
    size_t getMaxBindings() const { return mState.getMaxBindings(); }

    const std::vector<VertexAttribute> &getVertexAttributes() const
    {
        return mState.getVertexAttributes();
    }
    const std::vector<VertexBinding> &getVertexBindings() const
    {
        return mState.getVertexBindings();
    }

    rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }

    const AttributesMask &getEnabledAttributesMask() const
    {
        return mState.getEnabledAttributesMask();
    }

    AttributesMask getClientAttribsMask() const { return mState.mClientMemoryAttribsMask; }

    bool hasEnabledNullPointerClientArray() const
    {
        return mState.hasEnabledNullPointerClientArray();
    }

    bool hasInvalidMappedArrayBuffer() const
    {
        return mState.mCachedInvalidMappedArrayBuffer.any();
    }

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

    bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; }

    // Observer implementation
    void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
    void onBufferContentsChange(uint32_t bufferIndex);

    static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit);

    angle::Result syncState(const Context *context);
    bool hasAnyDirtyBit() const { return mDirtyBits.any(); }

    ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; }
    AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }

    void onBindingChanged(const Context *context, int incr);
    bool hasTransformFeedbackBindingConflict(const Context *context) const;

    ANGLE_INLINE angle::Result getIndexRange(const Context *context,
                                             DrawElementsType type,
                                             GLsizei indexCount,
                                             const void *indices,
                                             IndexRange *indexRangeOut) const
    {
        Buffer *elementArrayBuffer = mState.mElementArrayBuffer.get();
        if (elementArrayBuffer && mIndexRangeCache.get(type, indexCount, indices, indexRangeOut))
        {
            return angle::Result::Continue;
        }

        return getIndexRangeImpl(context, type, indexCount, indices, indexRangeOut);
    }

    void setBufferAccessValidationEnabled(bool enabled)
    {
        mBufferAccessValidationEnabled = enabled;
    }

  private:
    ~VertexArray() override;

    // This is a performance optimization for buffer binding. Allows element array buffer updates.
    friend class State;

    void setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit);
    void setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit);
    void clearDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit);

    DirtyBitType getDirtyBitFromIndex(bool contentsChanged, angle::SubjectIndex index) const;
    void setDependentDirtyBit(bool contentsChanged, angle::SubjectIndex index);

    // These are used to optimize draw call validation.
    void updateCachedBufferBindingSize(VertexBinding *binding);
    void updateCachedTransformFeedbackBindingValidation(size_t bindingIndex, const Buffer *buffer);
    void updateCachedArrayBuffersMasks(bool isMapped,
                                       bool isImmutable,
                                       bool isPersistent,
                                       const AttributesMask &boundAttributesMask);
    void updateCachedMappedArrayBuffersBinding(const VertexBinding &binding);

    angle::Result getIndexRangeImpl(const Context *context,
                                    DrawElementsType type,
                                    GLsizei indexCount,
                                    const void *indices,
                                    IndexRange *indexRangeOut) const;

    void setVertexAttribPointerImpl(const Context *context,
                                    ComponentType componentType,
                                    bool pureInteger,
                                    size_t attribIndex,
                                    Buffer *boundBuffer,
                                    GLint size,
                                    VertexAttribType type,
                                    bool normalized,
                                    GLsizei stride,
                                    const void *pointer);

    // These two functions return true if the state was dirty.
    bool setVertexAttribFormatImpl(VertexAttribute *attrib,
                                   GLint size,
                                   VertexAttribType type,
                                   bool normalized,
                                   bool pureInteger,
                                   GLuint relativeOffset);

    DirtyBindingBits bindVertexBufferImpl(const Context *context,
                                          size_t bindingIndex,
                                          Buffer *boundBuffer,
                                          GLintptr offset,
                                          GLsizei stride);

    void onBind(const Context *context);
    void onUnbind(const Context *context);

    VertexArrayID mId;

    VertexArrayState mState;
    DirtyBits mDirtyBits;
    DirtyAttribBitsArray mDirtyAttribBits;
    DirtyBindingBitsArray mDirtyBindingBits;
    Optional<DirtyBits> mDirtyBitsGuard;

    rx::VertexArrayImpl *mVertexArray;

    std::vector<angle::ObserverBinding> mArrayBufferObserverBindings;

    AttributesMask mCachedTransformFeedbackConflictedBindingsMask;

    class IndexRangeCache final : angle::NonCopyable
    {
      public:
        IndexRangeCache();

        void invalidate() { mTypeKey = DrawElementsType::InvalidEnum; }

        bool get(DrawElementsType type,
                 GLsizei indexCount,
                 const void *indices,
                 IndexRange *indexRangeOut)
        {
            size_t offset = reinterpret_cast<uintptr_t>(indices);
            if (mTypeKey == type && mIndexCountKey == indexCount && mOffsetKey == offset)
            {
                *indexRangeOut = mPayload;
                return true;
            }

            return false;
        }

        void put(DrawElementsType type,
                 GLsizei indexCount,
                 size_t offset,
                 const IndexRange &indexRange);

      private:
        DrawElementsType mTypeKey;
        GLsizei mIndexCountKey;
        size_t mOffsetKey;
        IndexRange mPayload;
    };

    mutable IndexRangeCache mIndexRangeCache;
    bool mBufferAccessValidationEnabled;
    VertexArrayBufferContentsObservers mContentsObservers;
};

}  // namespace gl

#endif  // LIBANGLE_VERTEXARRAY_H_
