|  | // 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 <vector> | 
|  |  | 
|  | #include "base/containers/hash_tables.h" | 
|  | #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_; | 
|  |  | 
|  | base::hash_map<std::string, GLint> frag_data_locations_; | 
|  | base::hash_map<std::string, GLint> frag_data_indices_; | 
|  | }; | 
|  |  | 
|  | Program* GetProgramInfo( | 
|  | GLES2Implementation* gl, GLuint program, ProgramInfoType type); | 
|  |  | 
|  | typedef base::hash_map<GLuint, Program> ProgramInfoMap; | 
|  |  | 
|  | ProgramInfoMap program_infos_; | 
|  |  | 
|  | mutable base::Lock lock_; | 
|  | }; | 
|  |  | 
|  | }  // namespace gles2 | 
|  | }  // namespace gpu | 
|  |  | 
|  | #endif  // GPU_COMMAND_BUFFER_CLIENT_PROGRAM_INFO_MANAGER_H_ |