// 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_SERVICE_SHADER_MANAGER_H_ #define GPU_COMMAND_BUFFER_SERVICE_SHADER_MANAGER_H_ #include <string> #include "base/basictypes.h" #include "base/containers/hash_tables.h" #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/shader_translator.h" #include "gpu/gpu_export.h" namespace gpu { namespace gles2 { // This is used to keep the source code for a shader. This is because in order // to emluate GLES2 the shaders will have to be re-written before passed to // the underlying OpenGL. But, when the user calls glGetShaderSource they // should get the source they passed in, not the re-written source. class GPU_EXPORT Shader : public base::RefCounted<Shader> { public: enum TranslatedShaderSourceType { kANGLE, kGL, // GL or GLES }; enum ShaderState { kShaderStateWaiting, kShaderStateCompileRequested, kShaderStateCompiled, // Signifies compile happened, not valid compile. }; static const int kUndefinedShaderVersion = -1; void RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator, TranslatedShaderSourceType type); void DoCompile(); ShaderState shader_state() const { return shader_state_; } GLuint service_id() const { return marked_for_deletion_ ? 0 : service_id_; } GLenum shader_type() const { return shader_type_; } int shader_version() const { return shader_version_; } const std::string& source() const { return source_; } void set_source(const std::string& source) { source_ = source; } const std::string& translated_source() const { return translated_source_; } std::string last_compiled_source() const { return last_compiled_source_; } std::string last_compiled_signature() const { if (translator_.get()) { return last_compiled_source_ + translator_->GetStringForOptionsThatWouldAffectCompilation(); } return last_compiled_source_; } const sh::Attribute* GetAttribInfo(const std::string& name) const; const sh::Uniform* GetUniformInfo(const std::string& name) const; const sh::Varying* GetVaryingInfo(const std::string& name) const; // If the original_name is not found, return NULL. const std::string* GetAttribMappedName( const std::string& original_name) const; // If the hashed_name is not found, return NULL. const std::string* GetOriginalNameFromHashedName( const std::string& hashed_name) const; const std::string& log_info() const { return log_info_; } bool valid() const { return shader_state_ == kShaderStateCompiled && valid_; } bool IsDeleted() const { return marked_for_deletion_; } bool InUse() const { DCHECK_GE(use_count_, 0); return use_count_ != 0; } // Used by program cache. const AttributeMap& attrib_map() const { return attrib_map_; } // Used by program cache. const UniformMap& uniform_map() const { return uniform_map_; } // Used by program cache. const VaryingMap& varying_map() const { return varying_map_; } // Used by program cache. void set_attrib_map(const AttributeMap& attrib_map) { // copied because cache might be cleared attrib_map_ = AttributeMap(attrib_map); } // Used by program cache. void set_uniform_map(const UniformMap& uniform_map) { // copied because cache might be cleared uniform_map_ = UniformMap(uniform_map); } // Used by program cache. void set_varying_map(const VaryingMap& varying_map) { // copied because cache might be cleared varying_map_ = VaryingMap(varying_map); } private: friend class base::RefCounted<Shader>; friend class ShaderManager; Shader(GLuint service_id, GLenum shader_type); ~Shader(); // Must be called only if we currently own the context. Forces the deletion // of the underlying shader service id. void Destroy(); void IncUseCount(); void DecUseCount(); void MarkForDeletion(); void DeleteServiceID(); int use_count_; // The current state of the shader. ShaderState shader_state_; // The shader has been marked for deletion. bool marked_for_deletion_; // The shader this Shader is tracking. GLuint service_id_; // Type of shader - GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. GLenum shader_type_; // Version of the shader. Can be kUndefinedShaderVersion or version returned // by ANGLE. int shader_version_; // Translated source type when shader was last requested to be compiled. TranslatedShaderSourceType source_type_; // Translator to use, set when shader was last requested to be compiled. scoped_refptr<ShaderTranslatorInterface> translator_; // True if compilation succeeded. bool valid_; // The shader source as passed to glShaderSource. std::string source_; // The source the last compile used. std::string last_compiled_source_; // The translated shader source. std::string translated_source_; // The shader translation log. std::string log_info_; // The type info when the shader was last compiled. AttributeMap attrib_map_; UniformMap uniform_map_; VaryingMap varying_map_; // The name hashing info when the shader was last compiled. NameMap name_map_; }; // Tracks the Shaders. // // NOTE: To support shared resources an instance of this class will // need to be shared by multiple GLES2Decoders. class GPU_EXPORT ShaderManager { public: ShaderManager(); ~ShaderManager(); // Must call before destruction. void Destroy(bool have_context); // Creates a shader for the given shader ID. Shader* CreateShader( GLuint client_id, GLuint service_id, GLenum shader_type); // Gets an existing shader info for the given shader ID. Returns NULL if none // exists. Shader* GetShader(GLuint client_id); // Gets a client id for a given service id. bool GetClientId(GLuint service_id, GLuint* client_id) const; void Delete(Shader* shader); // Mark a shader as used void UseShader(Shader* shader); // Unmark a shader as used. If it has been deleted and is not used // then we free the shader. void UnuseShader(Shader* shader); // Check if a Shader is owned by this ShaderManager. bool IsOwned(Shader* shader); private: friend class Shader; // Info for each shader by service side shader Id. typedef base::hash_map<GLuint, scoped_refptr<Shader> > ShaderMap; ShaderMap shaders_; void RemoveShader(Shader* shader); DISALLOW_COPY_AND_ASSIGN(ShaderManager); }; } // namespace gles2 } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_SHADER_MANAGER_H_