// Copyright (c) 2012 The Chromium 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 GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_
#define GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_

#include <GLES3/gl3.h>
#include <stdint.h>

#include <string>
#include <unordered_map>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/synchronization/lock.h"
#include "gles2_impl_export.h"
#include "gpu/command_buffer/client/gles2_implementation.h"

namespace gpu {
namespace gles2 {

// Manages info about OpenGL ES Programs.
class GLES2_IMPL_EXPORT ProgramInfoManager {
 public:
  ProgramInfoManager();
  ~ProgramInfoManager();

  void CreateInfo(GLuint program);

  void DeleteInfo(GLuint program);

  bool GetProgramiv(
      GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params);

  GLint GetAttribLocation(
      GLES2Implementation* gl, GLuint program, const char* name);

  GLint GetUniformLocation(
      GLES2Implementation* gl, GLuint program, const char* name);

  GLint GetFragDataIndex(GLES2Implementation* gl,
                         GLuint program,
                         const char* name);

  GLint GetFragDataLocation(
      GLES2Implementation* gl, GLuint program, const char* name);

  bool GetActiveAttrib(
      GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
      GLsizei* length, GLint* size, GLenum* type, char* name);

  bool GetActiveUniform(
      GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
      GLsizei* length, GLint* size, GLenum* type, char* name);

  GLuint GetUniformBlockIndex(
      GLES2Implementation* gl, GLuint program, const char* name);

  bool GetActiveUniformBlockName(
      GLES2Implementation* gl, GLuint program, GLuint index,
      GLsizei buf_size, GLsizei* length, char* name);

  bool GetActiveUniformBlockiv(
      GLES2Implementation* gl, GLuint program, GLuint index,
      GLenum pname, GLint* params);

  // Attempt to update the |index| uniform block binding.
  // It's no op if the program does not exist, or the |index| uniform block
  // is not in the cache, or binding >= GL_MAX_UNIFORM_BUFFER_BINDINGS.
  void UniformBlockBinding(
      GLES2Implementation* gl, GLuint program, GLuint index, GLuint binding);

  bool GetTransformFeedbackVarying(
      GLES2Implementation* gl, GLuint program, GLuint index, GLsizei bufsize,
      GLsizei* length, GLsizei* size, GLenum* type, char* name);

  bool GetUniformIndices(
      GLES2Implementation* gl, GLuint program, GLsizei count,
      const char* const* names, GLuint* indices);

  bool GetActiveUniformsiv(
      GLES2Implementation* gl, GLuint program, GLsizei count,
      const GLuint* indices, GLenum pname, GLint* params);

 private:
  friend class ProgramInfoManagerTest;

  FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES2);
  FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest, UpdateES3UniformBlocks);
  FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest,
                           UpdateES3TransformFeedbackVaryings);
  FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest,
                           GetActiveUniformsivCached);

  enum ProgramInfoType {
    kES2,
    kES3UniformBlocks,
    kES3TransformFeedbackVaryings,
    kES3Uniformsiv,
    kNone,
  };

  // Need GLES2_IMPL_EXPORT for tests.
  class GLES2_IMPL_EXPORT Program {
   public:
    struct UniformInfo {
      UniformInfo(GLsizei _size, GLenum _type, const std::string& _name);
      UniformInfo(const UniformInfo& other);
      ~UniformInfo();

      GLsizei size;
      GLenum type;
      bool is_array;
      std::string name;
      std::vector<GLint> element_locations;
    };
    struct UniformES3 {
      UniformES3();
      ~UniformES3();

      GLint block_index;
      GLint offset;
      GLint array_stride;
      GLint matrix_stride;
      GLint is_row_major;
    };
    struct VertexAttrib {
      VertexAttrib(GLsizei _size, GLenum _type, const std::string& _name,
                   GLint _location);
      ~VertexAttrib();

      GLsizei size;
      GLenum type;
      GLint location;
      std::string name;
    };
    struct UniformBlock {
      UniformBlock();
      UniformBlock(const UniformBlock& other);
      ~UniformBlock();

      GLuint binding;
      GLuint data_size;
      std::vector<GLuint> active_uniform_indices;
      GLboolean referenced_by_vertex_shader;
      GLboolean referenced_by_fragment_shader;
      std::string name;
    };
    struct TransformFeedbackVarying {
      TransformFeedbackVarying();
      ~TransformFeedbackVarying();

      GLsizei size;
      GLenum type;
      std::string name;
    };

    Program();
    Program(const Program& other);
    ~Program();

    const VertexAttrib* GetAttribInfo(GLint index) const;

    GLint GetAttribLocation(const std::string& name) const;

    const UniformInfo* GetUniformInfo(GLint index) const;

    // Gets the location of a uniform by name.
    GLint GetUniformLocation(const std::string& name) const;
    // Gets the index of a uniform by name. Return INVALID_INDEX in failure.
    GLuint GetUniformIndex(const std::string& name) const;

    bool GetUniformsiv(
        GLsizei count, const GLuint* indices, GLenum pname, GLint* params);

    GLint GetFragDataIndex(const std::string& name) const;
    void CacheFragDataIndex(const std::string& name, GLint index);

    GLint GetFragDataLocation(const std::string& name) const;
    void CacheFragDataLocation(const std::string& name, GLint loc);

    bool GetProgramiv(GLenum pname, GLint* params);

    // Gets the index of a uniform block by name.
    GLuint GetUniformBlockIndex(const std::string& name) const;
    const UniformBlock* GetUniformBlock(GLuint index) const;
    // Update the binding if the |index| uniform block is in the cache.
    void UniformBlockBinding(GLuint index, GLuint binding);

    const TransformFeedbackVarying* GetTransformFeedbackVarying(
        GLuint index) const;

    // Updates the ES2 only program info after a successful link.
    void UpdateES2(const std::vector<int8_t>& result);

    // Updates the ES3 UniformBlock info after a successful link.
    void UpdateES3UniformBlocks(const std::vector<int8_t>& result);

    // Updates the ES3 Uniformsiv info after a successful link.
    void UpdateES3Uniformsiv(const std::vector<int8_t>& result);

    // Updates the ES3 TransformFeedbackVaryings info after a successful link.
    void UpdateES3TransformFeedbackVaryings(const std::vector<int8_t>& result);

    bool IsCached(ProgramInfoType type) const;

   private:
    bool cached_es2_;

    GLsizei max_attrib_name_length_;

    // Attrib by index.
    std::vector<VertexAttrib> attrib_infos_;

    GLsizei max_uniform_name_length_;

    // Uniform info by index.
    std::vector<UniformInfo> uniform_infos_;

    // This is true if glLinkProgram was successful last time it was called.
    bool link_status_;

    // BELOW ARE ES3 ONLY INFORMATION.

    bool cached_es3_uniform_blocks_;

    uint32_t active_uniform_block_max_name_length_;

    // Uniform blocks by index.
    std::vector<UniformBlock> uniform_blocks_;

    bool cached_es3_transform_feedback_varyings_;

    uint32_t transform_feedback_varying_max_length_;
    GLenum transform_feedback_buffer_mode_;

    // TransformFeedback varyings by index.
    std::vector<TransformFeedbackVarying> transform_feedback_varyings_;

    bool cached_es3_uniformsiv_;

    std::vector<UniformES3> uniforms_es3_;

    std::unordered_map<std::string, GLint> frag_data_locations_;
    std::unordered_map<std::string, GLint> frag_data_indices_;
  };

  Program* GetProgramInfo(
      GLES2Implementation* gl, GLuint program, ProgramInfoType type);

  typedef std::unordered_map<GLuint, Program> ProgramInfoMap;

  ProgramInfoMap program_infos_;

  mutable base::Lock lock_;
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_
