| // 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); |
| |
| bool GetProgramInterfaceiv( |
| GLES2Implementation* gl, GLuint program, GLenum program_interface, |
| GLenum pname, GLint* params); |
| |
| GLuint GetProgramResourceIndex( |
| GLES2Implementation* gl, GLuint program, GLenum program_interface, |
| const char* name); |
| |
| bool GetProgramResourceName( |
| GLES2Implementation* gl, GLuint program, GLenum program_interface, |
| GLuint index, GLsizei bufsize, GLsizei* length, char* name); |
| |
| bool GetProgramResourceiv( |
| GLES2Implementation* gl, GLuint program, GLenum program_interface, |
| GLuint index, GLsizei prop_count, const GLenum* props, GLsizei bufsize, |
| GLsizei* length, GLint* params); |
| |
| GLint GetProgramResourceLocation( |
| GLES2Implementation* gl, GLuint program, GLenum program_interface, |
| const char* name); |
| |
| 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_ |