| // 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 GPU_GLES2_EXPORT 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_EXTERNAL_2D_Y2Y_EXT: | |
| 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; | |
| } | |
| void IncrementActiveTransformFeedbackCount() { | |
| ++active_transform_feedback_count_; | |
| } | |
| void DecrementActiveTransformFeedbackCount(); | |
| bool IsActiveForTransformFeedback() const { | |
| return active_transform_feedback_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_; | |
| int active_transform_feedback_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_ |