// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
#define GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_

#include <stddef.h>
#include <stdint.h>

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

#include "base/check_op.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/ref_counted.h"
#include "gpu/command_buffer/service/common_decoder.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/shader_manager.h"
#include "gpu/gpu_gles2_export.h"

namespace gl {
class ProgressReporter;
}

namespace gpu {

class DecoderClient;
struct GpuPreferences;

namespace gles2 {

class FeatureInfo;
class ProgramCache;
class ProgramManager;
class Shader;
class ShaderManager;

enum class UniformApiType : uint32_t {
  kUniformNone = 0,
  kUniform1i = 1 << 0,
  kUniform2i = 1 << 1,
  kUniform3i = 1 << 2,
  kUniform4i = 1 << 3,
  kUniform1f = 1 << 4,
  kUniform2f = 1 << 5,
  kUniform3f = 1 << 6,
  kUniform4f = 1 << 7,
  kUniformMatrix2f = 1 << 8,
  kUniformMatrix3f = 1 << 9,
  kUniformMatrix4f = 1 << 10,
  kUniform1ui = 1 << 11,
  kUniform2ui = 1 << 12,
  kUniform3ui = 1 << 13,
  kUniform4ui = 1 << 14,
  kUniformMatrix2x3f = 1 << 15,
  kUniformMatrix2x4f = 1 << 16,
  kUniformMatrix3x2f = 1 << 17,
  kUniformMatrix3x4f = 1 << 18,
  kUniformMatrix4x2f = 1 << 19,
  kUniformMatrix4x3f = 1 << 20,
};

inline constexpr UniformApiType operator|(UniformApiType a, UniformApiType b) {
  return static_cast<UniformApiType>(uint32_t(a) | uint32_t(b));
}

inline constexpr UniformApiType operator&(UniformApiType a, UniformApiType b) {
  return static_cast<UniformApiType>(uint32_t(a) & uint32_t(b));
}

// This is used to track which attributes a particular program needs
// so we can verify at glDrawXXX time that every attribute is either disabled
// or if enabled that it points to a valid source.
class GPU_GLES2_EXPORT Program : public base::RefCounted<Program> {
 public:
  static const int kMaxAttachedShaders = 2;

  struct ProgramOutputInfo {
    ProgramOutputInfo(GLuint _color_name,
                      GLuint _index,
                      const std::string& _name)
        : color_name(_color_name), index(_index), name(_name) {}
    ProgramOutputInfo() : color_name(0), index(0) {}
    GLuint color_name;
    GLuint index;
    std::string name;
  };

  struct UniformInfo {
    UniformInfo();
    UniformInfo(const UniformInfo& other);
    UniformInfo(const std::string& client_name,
                GLint client_location_base,
                GLenum _type,
                bool _is_array,
                const std::vector<GLint>& service_locations);
    ~UniformInfo();
    bool IsSampler() const {
      switch (type) {
        case GL_SAMPLER_2D:
        case GL_SAMPLER_2D_RECT_ANGLE:
        case GL_SAMPLER_CUBE:
        case GL_SAMPLER_EXTERNAL_OES:
        case GL_SAMPLER_3D:
        case GL_SAMPLER_2D_SHADOW:
        case GL_SAMPLER_2D_ARRAY:
        case GL_SAMPLER_2D_ARRAY_SHADOW:
        case GL_SAMPLER_CUBE_SHADOW:
        case GL_INT_SAMPLER_2D:
        case GL_INT_SAMPLER_3D:
        case GL_INT_SAMPLER_CUBE:
        case GL_INT_SAMPLER_2D_ARRAY:
        case GL_UNSIGNED_INT_SAMPLER_2D:
        case GL_UNSIGNED_INT_SAMPLER_3D:
        case GL_UNSIGNED_INT_SAMPLER_CUBE:
        case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
          return true;
        default:
          return false;
      }
    }

    GLsizei size;
    GLenum type;
    UniformApiType accepts_api_type;
    GLint fake_location_base;
    bool is_array;
    std::string name;
    std::vector<GLint> element_locations;
    std::vector<GLuint> texture_units;
  };
  struct VertexAttrib {
    VertexAttrib(GLsizei size,
                 GLenum type,
                 const std::string& name,
                 GLint location,
                 size_t location_count)
        : size(size),
          type(type),
          location(location),
          location_count(location_count),
          name(name) {}
    GLsizei size;
    GLenum type;
    GLint location;
    size_t location_count;
    std::string name;
  };
  struct UniformBlockSizeInfo {
    uint32_t binding;
    uint32_t data_size;
  };

  template <typename T>
  class ShaderVariableLocationEntry {
   public:
    ShaderVariableLocationEntry()
        : shader_variable_(nullptr), inactive_(false) {}
    bool IsUnused() const { return !shader_variable_ && !inactive_; }
    bool IsInactive() const { return inactive_; }
    bool IsActive() const { return shader_variable_ != nullptr; }
    void SetInactive() {
      shader_variable_ = nullptr;
      inactive_ = true;
    }
    void SetActive(T* shader_variable) {
      DCHECK(shader_variable);
      shader_variable_ = shader_variable;
      inactive_ = false;
    }
    const T* shader_variable() const {
      DCHECK(IsActive());
      return shader_variable_;
    }
    T* shader_variable() {
      DCHECK(IsActive());
      return shader_variable_;
    }

   private:
    raw_ptr<T> shader_variable_;  // Pointer to *_info_ vector entry.
    bool inactive_;
  };

  typedef std::vector<UniformInfo> UniformInfoVector;
  typedef std::vector<ShaderVariableLocationEntry<UniformInfo>>
      UniformLocationVector;
  typedef std::vector<VertexAttrib> AttribInfoVector;
  typedef std::vector<ProgramOutputInfo> ProgramOutputInfoVector;
  typedef std::vector<int> SamplerIndices;
  typedef std::map<std::string, GLint> LocationMap;
  typedef std::map<std::string, std::pair<GLuint, GLuint>> LocationIndexMap;
  typedef std::vector<std::string> StringVector;

  Program(ProgramManager* manager, GLuint service_id);

  GLuint service_id() const {
    return service_id_;
  }

  const SamplerIndices& sampler_indices() {
    return sampler_indices_;
  }

  const AttribInfoVector& GetAttribInfos() const {
    return attrib_infos_;
  }

  const VertexAttrib* GetAttribInfo(GLint index) const {
    return (static_cast<size_t>(index) < attrib_infos_.size())
               ? &attrib_infos_[index]
               : nullptr;
  }

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

  const VertexAttrib* GetAttribInfoByLocation(GLuint location) const {
    if (location < attrib_location_to_index_map_.size()) {
      GLint index = attrib_location_to_index_map_[location];
      if (index >= 0) {
        return &attrib_infos_[index];
      }
    }
    return nullptr;
  }

  const UniformInfo* GetUniformInfo(GLint index) const;

  // If the original name is not found, return nullptr.
  const std::string* GetAttribMappedName(
      const std::string& original_name) const;

  // If the original name is not found, return nullptr.
  const std::string* GetUniformMappedName(
      const std::string& original_name) const;

  // If the hashed name name is not found, return nullptr.
  // Use this only when one of the more specific Get*Info methods can't be used.
  const std::string* GetOriginalNameFromHashedName(
      const std::string& hashed_name) const;

  // If the hashed name is not found, return nullptr.
  const sh::Varying* GetVaryingInfo(const std::string& hashed_name) const;

  // If the hashed name is not found, return nullptr.
  const sh::InterfaceBlock* GetInterfaceBlockInfo(
      const std::string& hashed_name) const;

  // Gets the fake location of a uniform by name.
  GLint GetUniformFakeLocation(const std::string& name) const;

  // Gets the UniformInfo of a uniform by location.
  const UniformInfo* GetUniformInfoByFakeLocation(
      GLint fake_location, GLint* real_location, GLint* array_index) const;

  // Returns true if |fake_location| is a location for an inactive uniform,
  // -1 for bound, non-existing uniform.
  bool IsInactiveUniformLocationByFakeLocation(GLint fake_location) const;

  // Gets the ProgramOutputInfo of a fragment output by name.
  const ProgramOutputInfo* GetProgramOutputInfo(
      const std::string& original_name) const;

  // Gets all the program info.
  void GetProgramInfo(
      ProgramManager* manager, CommonDecoder::Bucket* bucket) const;

  // Gets all the UniformBlock info.
  // Return false on overflow.
  bool GetUniformBlocks(CommonDecoder::Bucket* bucket) const;

  // Gets all the TransformFeedbackVarying info.
  // Return false on overflow.
  bool GetTransformFeedbackVaryings(CommonDecoder::Bucket* bucket) const;

  // Gather all info through glGetActiveUniformsiv, except for size, type,
  // name_length, which we gather through glGetActiveUniform in
  // glGetProgramInfoCHROMIUM.
  bool GetUniformsES3(CommonDecoder::Bucket* bucket) const;

  // Returns the fragment shader output variable color name binding.
  // Returns -1 if |original_name| is not an out variable or error.
  GLint GetFragDataLocation(const std::string& original_name) const;

  // Returns the fragment shader output variable color index binding.
  // Returns -1 if |original_name| is not an out variable or error.
  GLint GetFragDataIndex(const std::string& original_name) const;

  // Sets the sampler values for a uniform.
  // This should be called only for valid fake location pointing to
  // an active uniform.
  // If the location is not a sampler uniform nothing will happen.
  // Returns false if fake_location is a sampler and any value is >=
  // num_texture_units. Returns true otherwise.
  bool SetSamplers(
      GLint num_texture_units, GLint fake_location,
      GLsizei count, const GLint* value);

  bool IsDeleted() const {
    return deleted_;
  }

  void GetProgramiv(GLenum pname, GLint* params);

  bool IsValid() const {
    return valid_;
  }

  bool IsShaderAttached(Shader* shader);
  bool AttachShader(ShaderManager* manager, Shader* shader);
  void DetachShader(ShaderManager* manager, Shader* shader);

  void CompileAttachedShaders();
  bool AttachedShadersExist() const;
  bool CanLink() const;

  // Performs glLinkProgram and related activities.
  bool Link(ShaderManager* manager,
            DecoderClient* client);

  // Performs glValidateProgram and related activities.
  void Validate();

  const std::string* log_info() const {
    return log_info_.get();
  }

  bool InUse() const {
    DCHECK_GE(use_count_, 0);
    return use_count_ != 0;
  }

  // Sets attribute-location binding from a glBindAttribLocation() call.
  void SetAttribLocationBinding(const std::string& attrib, GLint location) {
    bind_attrib_location_map_[attrib] = location;
  }

  // Sets uniform-location binding from a glBindUniformLocationCHROMIUM call.
  // returns false if error.
  bool SetUniformLocationBinding(const std::string& name, GLint location);

  // Detects if the shader version combination is not valid.
  bool DetectShaderVersionMismatch() const;

  // Sets program output variable location. Also sets color index to zero.
  void SetProgramOutputLocationBinding(const std::string& name,
                                       GLuint colorName);

  // Sets program output variable location and color index.
  void SetProgramOutputLocationIndexedBinding(const std::string& name,
                                              GLuint colorName,
                                              GLuint index);

  // Detects if there are attribute location conflicts from
  // glBindAttribLocation() calls.
  // We only consider the declared attributes in the program.
  bool DetectAttribLocationBindingConflicts() const;

  // Detects if there are uniform location conflicts from
  // glBindUniformLocationCHROMIUM() calls.
  // We only consider the statically used uniforms in the program.
  bool DetectUniformLocationBindingConflicts() const;

  // Detects if there are uniforms of the same name but different type
  // or precision in vertex/fragment shaders.
  // Return true and set the first found conflicting hashed name to
  // conflicting_name if such cases are detected.
  bool DetectUniformsMismatch(std::string* conflicting_name) const;

  // Detects if there are interface blocks of the same name but different
  // layouts.
  bool DetectInterfaceBlocksMismatch(std::string* conflicting_name) const;

  // Return true if a varying is statically used in fragment shader, but it
  // is not declared in vertex shader.
  bool DetectVaryingsMismatch(std::string* conflicting_name) const;

  // Detects if there are program output location conflicts from
  // glBindFragDataLocation and ..LocationIndexedEXT calls.
  // We only consider the statically used program outputs in the program.
  bool DetectProgramOutputLocationBindingConflicts() const;

  // Return true if any built-in invariant matching rules are broken as in
  // GLSL ES spec 1.00.17, section 4.6.4, Invariance and Linkage.
  bool DetectBuiltInInvariantConflicts() const;

  // Return true if an uniform and an attribute share the same name.
  bool DetectGlobalNameConflicts(std::string* conflicting_name) const;

  // Return false if varyings can't be packed into the max available
  // varying registers.
  bool CheckVaryingsPacking() const;

  void TransformFeedbackVaryings(GLsizei count, const char* const* varyings,
      GLenum buffer_mode);

  // Visible for testing
  const LocationMap& bind_attrib_location_map() const {
    return bind_attrib_location_map_;
  }

  const std::vector<std::string>& effective_transform_feedback_varyings()
      const {
    return effective_transform_feedback_varyings_;
  }

  GLenum effective_transform_feedback_buffer_mode() const {
    return effective_transform_feedback_buffer_mode_;
  }

  GLint draw_id_uniform_location() const { return draw_id_uniform_location_; }

  GLint base_vertex_uniform_location() const {
    return base_vertex_uniform_location_;
  }

  GLint base_instance_uniform_location() const {
    return base_instance_uniform_location_;
  }

  // See member declaration for details.
  // The data are only valid after a successful link.
  uint32_t fragment_output_type_mask() const {
    return fragment_output_type_mask_;
  }
  uint32_t fragment_output_written_mask() const {
    return fragment_output_written_mask_;
  }

  // The data are only valid after a successful link.
  const std::vector<uint32_t>& vertex_input_base_type_mask() const {
    return vertex_input_base_type_mask_;
  }
  const std::vector<uint32_t>& vertex_input_active_mask() const {
    return vertex_input_active_mask_;
  }

  // Update uniform block binding after a successful glUniformBlockBinding().
  void SetUniformBlockBinding(GLuint index, GLuint binding);

  const std::vector<UniformBlockSizeInfo>& uniform_block_size_info() const {
    return uniform_block_size_info_;
  }

  // Return the transform feedback varying sizes (per vertex).
  // Note that if the bufferMode is GL_INTERLEAVED_ATTRIBS, then there is only
  // one entry and it is the sum of all varying sizes.
  const std::vector<GLsizeiptr>& GetTransformFeedbackVaryingSizes() const {
    return transform_feedback_data_size_per_vertex_;
  }

 private:
  friend class base::RefCounted<Program>;
  friend class ProgramManager;

  ~Program();

  void set_log_info(const char* str) {
    log_info_.reset(str ? new std::string(str) : nullptr);
  }

  void ClearLinkStatus() {
    link_status_ = false;
  }

  void IncUseCount() {
    ++use_count_;
  }

  void DecUseCount() {
    --use_count_;
    DCHECK_GE(use_count_, 0);
  }

  void MarkAsDeleted() {
    DCHECK(!deleted_);
    deleted_ =  true;
  }

  // Resets the program.
  void Reset();

  // Updates the program info after a successful link.
  void Update();
  bool UpdateUniforms();
  void UpdateProgramOutputs();
  void UpdateFragmentOutputBaseTypes();
  void UpdateVertexInputBaseTypes();
  void UpdateUniformBlockSizeInfo();
  void UpdateTransformFeedbackInfo();

  // Process the program log, replacing the hashed names with original names.
  std::string ProcessLogInfo(const std::string& log);

  // Updates the program log info from GL
  void UpdateLogInfo();

  // Updates the draw id uniform location used by ANGLE_multi_draw
  void UpdateDrawIDUniformLocation();

  // Updates the base vertex and base instance uniform location used by
  // ANGLE_base_vertex_base_instance
  void UpdateBaseVertexUniformLocation();

  void UpdateBaseInstanceUniformLocation();

  // If long attribate names are mapped during shader translation, call
  // glBindAttribLocation() again with the mapped names.
  // This is called right before the glLink() call, but after shaders are
  // translated.
  void ExecuteBindAttribLocationCalls();

  // The names of transform feedback varyings need to be hashed just
  // like bound attributes' locations, just before the link call.
  // Returns false upon failure.
  bool ExecuteTransformFeedbackVaryingsCall();

  void ExecuteProgramOutputBindCalls();

  // Query VertexAttrib data returned by ANGLE translator by the mapped name.
  void GetVertexAttribData(
      const std::string& name, std::string* original_name, GLenum* type) const;

  void DetachShaders(ShaderManager* manager);

  static inline size_t GetUniformLocationIndexFromFakeLocation(
      GLint fake_location) {
    return static_cast<size_t>(fake_location & 0xFFFF);
  }

  static inline size_t GetArrayElementIndexFromFakeLocation(
      GLint fake_location) {
    return static_cast<size_t>((fake_location >> 16) & 0xFFFF);
  }

  const FeatureInfo& feature_info() const;

  void ClearVertexInputMasks();

  raw_ptr<ProgramManager> manager_;

  int use_count_;

  GLsizei max_attrib_name_length_;

  // Attrib by index.
  AttribInfoVector attrib_infos_;

  // Attrib by location to index.
  std::vector<GLint> attrib_location_to_index_map_;

  GLsizei max_uniform_name_length_;

  // Uniform info by index.
  UniformInfoVector uniform_infos_;
  UniformLocationVector uniform_locations_;

  // The indices of the uniforms that are samplers.
  SamplerIndices sampler_indices_;

  ProgramOutputInfoVector program_output_infos_;

  // The program this Program is tracking.
  GLuint service_id_;

  // Shaders by type of shader.
  std::array<scoped_refptr<Shader>, kMaxAttachedShaders> attached_shaders_;
  std::array<scoped_refptr<Shader>, kMaxAttachedShaders>
      shaders_from_last_successful_link_;

  // True if this program is marked as deleted.
  bool deleted_;

  // This is true if glLinkProgram was successful at least once.
  bool valid_;

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

  // True if the uniforms have been cleared.
  bool uniforms_cleared_;

  // ANGLE_multi_draw
  GLint draw_id_uniform_location_;

  // ANGLE_base_vertex_base_instance
  GLint base_vertex_uniform_location_;
  GLint base_instance_uniform_location_;

  // Log info
  std::unique_ptr<std::string> log_info_;

  // attribute-location binding map from glBindAttribLocation() calls.
  LocationMap bind_attrib_location_map_;

  // uniform-location binding map from glBindUniformLocationCHROMIUM() calls.
  LocationMap bind_uniform_location_map_;

  // Set by glTransformFeedbackVaryings().
  std::vector<std::string> transform_feedback_varyings_;
  GLenum transform_feedback_buffer_mode_;

  // After a successful link.
  std::vector<std::string> effective_transform_feedback_varyings_;
  GLenum effective_transform_feedback_buffer_mode_;
  // If buffer mode is INTERLEVED, there is only one entry; otherwise there
  // might be multiple entries, one per transform feedback varying.
  // The size requirement is per vertex. Total minimum buffer size requirment
  // is calculated at DrawArrays{Instanced} time by multiplying vertex count.
  std::vector<GLsizeiptr> transform_feedback_data_size_per_vertex_;

  // output variable - (location,index) binding map from
  // glBindFragDataLocation() and ..IndexedEXT() calls.
  LocationIndexMap bind_program_output_location_index_map_;

  // It's stored in the order of uniform block indices, i.e., the first
  // entry is the info about UniformBlock with index 0, etc.
  std::vector<UniformBlockSizeInfo> uniform_block_size_info_;

  // Fragment output variable base types: FLOAT, INT, or UINT.
  // We have up to 16 outputs, each is encoded into 2 bits, total 32 bits:
  // the lowest 2 bits for location 0, the highest 2 bits for location 15.
  uint32_t fragment_output_type_mask_;
  // Same layout as above, 2 bits per location, 0x03 if a location is occupied
  // by an output variable, 0x00 if not.
  uint32_t fragment_output_written_mask_;

  // Vertex input attrib base types: FLOAT, INT, or UINT.
  // Each base type is encoded into 2 bits, the lowest 2 bits for location 0,
  // the highest 2 bits for location (max_vertex_attribs - 1).
  std::vector<uint32_t> vertex_input_base_type_mask_;
  // Same layout as above, 2 bits per location, 0x03 if a location is set
  // by vertexAttrib API, 0x00 if not.
  std::vector<uint32_t> vertex_input_active_mask_;
};

// Tracks the Programs.
//
// NOTE: To support shared resources an instance of this class will
// need to be shared by multiple GLES2Decoders.
class GPU_GLES2_EXPORT ProgramManager {
 public:
  ProgramManager(ProgramCache* program_cache,
                 uint32_t max_varying_vectors,
                 uint32_t max_draw_buffers,
                 uint32_t max_dual_source_draw_buffers,
                 uint32_t max_vertex_attribs,
                 const GpuPreferences& gpu_preferences,
                 FeatureInfo* feature_info,
                 gl::ProgressReporter* progress_reporter);

  ProgramManager(const ProgramManager&) = delete;
  ProgramManager& operator=(const ProgramManager&) = delete;

  ~ProgramManager();

  // Must call before destruction.
  void Destroy(bool have_context);

  // Creates a new program.
  Program* CreateProgram(GLuint client_id, GLuint service_id);

  // Gets a program.
  Program* GetProgram(GLuint client_id);

  // Gets a client id for a given service id.
  bool GetClientId(GLuint service_id, GLuint* client_id) const;

  // Gets the shader cache
  ProgramCache* program_cache() const;

  // Marks a program as deleted. If it is not used the program will be deleted.
  void MarkAsDeleted(ShaderManager* shader_manager, Program* program);

  // Marks a program as used.
  void UseProgram(Program* program);

  // Makes a program as unused. If deleted the program will be removed.
  void UnuseProgram(ShaderManager* shader_manager, Program* program);

  // Updates the draw id location for this program for ANGLE_multi_draw
  void UpdateDrawIDUniformLocation(Program* program);

  // Updates the base vertex location for this program for
  // ANGLE_base_vertex_base_instance
  void UpdateBaseVertexUniformLocation(Program* program);

  // Updates the base instance location for this program for
  // ANGLE_base_vertex_base_instance
  void UpdateBaseInstanceUniformLocation(Program* program);

  // Returns true if |name| has a prefix that is intended for GL built-in shader
  // variables.
  static bool HasBuiltInPrefix(const std::string& name);

  // Check if a Program is owned by this ProgramManager.
  bool IsOwned(Program* program) const;

  // Return true if this shader has compiled status cached.
  bool HasCachedCompileStatus(Shader* shader) const;

  static int32_t MakeFakeLocation(int32_t index, int32_t element);

  uint32_t max_varying_vectors() const { return max_varying_vectors_; }

  uint32_t max_draw_buffers() const { return max_draw_buffers_; }

  uint32_t max_dual_source_draw_buffers() const {
    return max_dual_source_draw_buffers_;
  }

  uint32_t max_vertex_attribs() const { return max_vertex_attribs_; }

 private:
  friend class Program;

  void StartTracking(Program* program);
  void StopTracking(Program* program);

  void RemoveProgramInfoIfUnused(
      ShaderManager* shader_manager, Program* program);

  // Info for each "successfully linked" program by service side program Id.
  // TODO(gman): Choose a faster container.
  typedef std::map<GLuint, scoped_refptr<Program> > ProgramMap;
  ProgramMap programs_;

  // Counts the number of Program allocated with 'this' as its manager.
  // Allows to check no Program will outlive this.
  unsigned int program_count_;

  bool have_context_;

  // Used to clear uniforms.
  std::vector<uint8_t> zero_;

  raw_ptr<ProgramCache> program_cache_;

  uint32_t max_varying_vectors_;
  uint32_t max_draw_buffers_;
  uint32_t max_dual_source_draw_buffers_;
  uint32_t max_vertex_attribs_;

  const raw_ref<const GpuPreferences> gpu_preferences_;
  scoped_refptr<FeatureInfo> feature_info_;

  // Used to notify the watchdog thread of progress during destruction,
  // preventing time-outs when destruction takes a long time. May be null when
  // using in-process command buffer.
  raw_ptr<gl::ProgressReporter> progress_reporter_;
};

inline const FeatureInfo& Program::feature_info() const {
  return *manager_->feature_info_.get();
}

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_MANAGER_H_
