1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/shader_manager.h" 6 7 #include <utility> 8 9 #include "base/logging.h" 10 #include "base/strings/string_util.h" 11 12 namespace gpu { 13 namespace gles2 { 14 15 Shader::Shader(GLuint service_id, GLenum shader_type) 16 : use_count_(0), 17 service_id_(service_id), 18 shader_type_(shader_type), 19 valid_(false) { 20 } 21 22 Shader::~Shader() { 23 } 24 25 void Shader::IncUseCount() { 26 ++use_count_; 27 } 28 29 void Shader::DecUseCount() { 30 --use_count_; 31 DCHECK_GE(use_count_, 0); 32 } 33 34 void Shader::MarkAsDeleted() { 35 DCHECK_NE(service_id_, 0u); 36 service_id_ = 0; 37 } 38 39 void Shader::SetStatus( 40 bool valid, const char* log, ShaderTranslatorInterface* translator) { 41 valid_ = valid; 42 log_info_.reset(log ? new std::string(log) : NULL); 43 if (translator && valid) { 44 attrib_map_ = translator->attrib_map(); 45 uniform_map_ = translator->uniform_map(); 46 varying_map_ = translator->varying_map(); 47 name_map_ = translator->name_map(); 48 } else { 49 attrib_map_.clear(); 50 uniform_map_.clear(); 51 varying_map_.clear(); 52 name_map_.clear(); 53 } 54 if (valid && source_.get()) { 55 signature_source_.reset(new std::string(source_->c_str())); 56 } else { 57 signature_source_.reset(); 58 } 59 } 60 61 const Shader::VariableInfo* 62 Shader::GetAttribInfo( 63 const std::string& name) const { 64 VariableMap::const_iterator it = attrib_map_.find(name); 65 return it != attrib_map_.end() ? &it->second : NULL; 66 } 67 68 const std::string* Shader::GetAttribMappedName( 69 const std::string& original_name) const { 70 for (VariableMap::const_iterator it = attrib_map_.begin(); 71 it != attrib_map_.end(); ++it) { 72 if (it->second.name == original_name) 73 return &(it->first); 74 } 75 return NULL; 76 } 77 78 const std::string* Shader::GetOriginalNameFromHashedName( 79 const std::string& hashed_name) const { 80 NameMap::const_iterator it = name_map_.find(hashed_name); 81 if (it != name_map_.end()) 82 return &(it->second); 83 return NULL; 84 } 85 86 const Shader::VariableInfo* 87 Shader::GetUniformInfo( 88 const std::string& name) const { 89 VariableMap::const_iterator it = uniform_map_.find(name); 90 return it != uniform_map_.end() ? &it->second : NULL; 91 } 92 93 ShaderManager::ShaderManager() {} 94 95 ShaderManager::~ShaderManager() { 96 DCHECK(shaders_.empty()); 97 } 98 99 void ShaderManager::Destroy(bool have_context) { 100 while (!shaders_.empty()) { 101 if (have_context) { 102 Shader* shader = shaders_.begin()->second.get(); 103 if (!shader->IsDeleted()) { 104 glDeleteShader(shader->service_id()); 105 shader->MarkAsDeleted(); 106 } 107 } 108 shaders_.erase(shaders_.begin()); 109 } 110 } 111 112 Shader* ShaderManager::CreateShader( 113 GLuint client_id, 114 GLuint service_id, 115 GLenum shader_type) { 116 std::pair<ShaderMap::iterator, bool> result = 117 shaders_.insert(std::make_pair( 118 client_id, scoped_refptr<Shader>( 119 new Shader(service_id, shader_type)))); 120 DCHECK(result.second); 121 return result.first->second.get(); 122 } 123 124 Shader* ShaderManager::GetShader(GLuint client_id) { 125 ShaderMap::iterator it = shaders_.find(client_id); 126 return it != shaders_.end() ? it->second.get() : NULL; 127 } 128 129 bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const { 130 // This doesn't need to be fast. It's only used during slow queries. 131 for (ShaderMap::const_iterator it = shaders_.begin(); 132 it != shaders_.end(); ++it) { 133 if (it->second->service_id() == service_id) { 134 *client_id = it->first; 135 return true; 136 } 137 } 138 return false; 139 } 140 141 bool ShaderManager::IsOwned(Shader* shader) { 142 for (ShaderMap::iterator it = shaders_.begin(); 143 it != shaders_.end(); ++it) { 144 if (it->second.get() == shader) { 145 return true; 146 } 147 } 148 return false; 149 } 150 151 void ShaderManager::RemoveShader(Shader* shader) { 152 DCHECK(shader); 153 DCHECK(IsOwned(shader)); 154 if (shader->IsDeleted() && !shader->InUse()) { 155 for (ShaderMap::iterator it = shaders_.begin(); 156 it != shaders_.end(); ++it) { 157 if (it->second.get() == shader) { 158 shaders_.erase(it); 159 return; 160 } 161 } 162 NOTREACHED(); 163 } 164 } 165 166 void ShaderManager::MarkAsDeleted(Shader* shader) { 167 DCHECK(shader); 168 DCHECK(IsOwned(shader)); 169 shader->MarkAsDeleted(); 170 RemoveShader(shader); 171 } 172 173 void ShaderManager::UseShader(Shader* shader) { 174 DCHECK(shader); 175 DCHECK(IsOwned(shader)); 176 shader->IncUseCount(); 177 } 178 179 void ShaderManager::UnuseShader(Shader* shader) { 180 DCHECK(shader); 181 DCHECK(IsOwned(shader)); 182 shader->DecUseCount(); 183 RemoveShader(shader); 184 } 185 186 } // namespace gles2 187 } // namespace gpu 188 189 190