//
// Copyright 2014 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.
//

#ifndef LIBANGLE_TRANSFORM_FEEDBACK_H_
#define LIBANGLE_TRANSFORM_FEEDBACK_H_

#include "libANGLE/RefCountObject.h"

#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "common/mathutil.h"
#include "libANGLE/Debug.h"

#include <optional>
#include "angle_gl.h"

namespace rx
{
class GLImplFactory;
class TransformFeedbackImpl;
class TransformFeedbackGL;
}  // namespace rx

namespace gl
{
class Buffer;
struct Caps;
class Context;
class Program;

angle::CheckedNumeric<GLsizeiptr> GetVerticesNeededForDraw(PrimitiveMode primitiveMode,
                                                           GLsizei count,
                                                           GLsizei primcount);

class TransformFeedbackState final : angle::NonCopyable
{
  public:
    TransformFeedbackState(size_t maxIndexedBuffers);
    ~TransformFeedbackState();

    const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t idx) const;
    const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const;
    const Program *getBoundProgram() const { return mProgram; }
    GLsizeiptr getVerticesDrawn() const { return mVerticesDrawn; }
    GLsizeiptr getPrimitivesDrawn() const;

  private:
    friend class TransformFeedback;

    std::string mLabel;

    bool mActive;
    PrimitiveMode mPrimitiveMode;
    bool mPaused;
    GLsizeiptr mVerticesDrawn;
    std::optional<GLsizeiptr> mVertexCapacity;

    Program *mProgram;
    ProgramPipeline *mProgramPipeline;
    ShaderMap<ShaderProgramID> mPPOPrograms;

    std::vector<OffsetBindingPointer<Buffer>> mIndexedBuffers;
};

class TransformFeedback final : public RefCountObject<TransformFeedbackID>, public LabeledObject
{
  public:
    TransformFeedback(rx::GLImplFactory *implFactory, TransformFeedbackID id, const Caps &caps);
    ~TransformFeedback() override;
    void onDestroy(const Context *context) override;

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

    angle::Result begin(const Context *context,
                        PrimitiveMode primitiveMode,
                        Program *program,
                        ProgramPipeline *programPipeline);
    angle::Result end(const Context *context);
    angle::Result pause(const Context *context);
    angle::Result resume(const Context *context);

    bool isActive() const { return mState.mActive; }

    bool isPaused() const;
    PrimitiveMode getPrimitiveMode() const;
    // Validates that the vertices produced by a draw call will fit in the bound transform feedback
    // buffers. primcounts may be nullptr for non-instanced draw calls.
    bool checkBufferSpaceForDraw(const Context *context,
                                 const GLsizei *counts,
                                 const GLsizei *primcounts,
                                 GLsizei drawcount);
    // This must be called after each draw call when transform feedback is enabled to keep track of
    // how many vertices have been written to the buffers. This information is needed by
    // checkBufferSpaceForDraw because each draw call appends vertices to the buffers starting just
    // after the last vertex of the previous draw call.
    void onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount);

    bool hasBoundProgram(ShaderProgramID program) const;
    bool hasBoundProgramPipeline(ProgramPipelineID programPipeline) const;
    bool hasSamePPOPrograms(ProgramPipeline *programPipeline) const;
    bool hasProgram() const { return mState.mProgram != nullptr; }
    bool hasProgramPipeline() const { return mState.mProgramPipeline != nullptr; }

    angle::Result bindIndexedBuffer(const Context *context,
                                    size_t index,
                                    Buffer *buffer,
                                    size_t offset,
                                    size_t size);
    const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t index) const;
    size_t getIndexedBufferCount() const;
    const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const;

    GLsizeiptr getVerticesDrawn() const { return mState.getVerticesDrawn(); }
    GLsizeiptr getPrimitivesDrawn() const { return mState.getPrimitivesDrawn(); }

    // Returns true if any buffer bound to this object is also bound to another target.
    bool buffersBoundForOtherUseInWebGL() const;

    // Returns true if the buffer is bound to any of the indexed binding points in this transform
    // feedback.
    bool isBufferBound(BufferID bufferID) const;
    void invalidateVertexCapacity() { mState.mVertexCapacity = std::nullopt; }

    angle::Result detachBuffer(const Context *context, BufferID bufferID);

    rx::TransformFeedbackImpl *getImplementation() const { return mImplementation; }

    void onBindingChanged(const Context *context, bool bound);

  private:
    void bindProgram(const Context *context, Program *program);
    void bindProgramPipeline(const Context *context, ProgramPipeline *programPipeline);
    void bindPPOPrograms(ProgramPipeline *programPipeline);

    TransformFeedbackState mState;
    rx::TransformFeedbackImpl *mImplementation;
};

}  // namespace gl

#endif  // LIBANGLE_TRANSFORM_FEEDBACK_H_
