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 name_map_ = translator->name_map(); 47 } else { 48 attrib_map_.clear(); 49 uniform_map_.clear(); 50 name_map_.clear(); 51 } 52 if (valid && source_.get()) { 53 signature_source_.reset(new std::string(source_->c_str())); 54 } else { 55 signature_source_.reset(); 56 } 57 } 58 59 const Shader::VariableInfo* 60 Shader::GetAttribInfo( 61 const std::string& name) const { 62 VariableMap::const_iterator it = attrib_map_.find(name); 63 return it != attrib_map_.end() ? &it->second : NULL; 64 } 65 66 const std::string* Shader::GetAttribMappedName( 67 const std::string& original_name) const { 68 for (VariableMap::const_iterator it = attrib_map_.begin(); 69 it != attrib_map_.end(); ++it) { 70 if (it->second.name == original_name) 71 return &(it->first); 72 } 73 return NULL; 74 } 75 76 const std::string* Shader::GetOriginalNameFromHashedName( 77 const std::string& hashed_name) const { 78 NameMap::const_iterator it = name_map_.find(hashed_name); 79 if (it != name_map_.end()) 80 return &(it->second); 81 return NULL; 82 } 83 84 const Shader::VariableInfo* 85 Shader::GetUniformInfo( 86 const std::string& name) const { 87 VariableMap::const_iterator it = uniform_map_.find(name); 88 return it != uniform_map_.end() ? &it->second : NULL; 89 } 90 91 ShaderManager::ShaderManager() {} 92 93 ShaderManager::~ShaderManager() { 94 DCHECK(shaders_.empty()); 95 } 96 97 void ShaderManager::Destroy(bool have_context) { 98 while (!shaders_.empty()) { 99 if (have_context) { 100 Shader* shader = shaders_.begin()->second.get(); 101 if (!shader->IsDeleted()) { 102 glDeleteShader(shader->service_id()); 103 shader->MarkAsDeleted(); 104 } 105 } 106 shaders_.erase(shaders_.begin()); 107 } 108 } 109 110 Shader* ShaderManager::CreateShader( 111 GLuint client_id, 112 GLuint service_id, 113 GLenum shader_type) { 114 std::pair<ShaderMap::iterator, bool> result = 115 shaders_.insert(std::make_pair( 116 client_id, scoped_refptr<Shader>( 117 new Shader(service_id, shader_type)))); 118 DCHECK(result.second); 119 return result.first->second.get(); 120 } 121 122 Shader* ShaderManager::GetShader(GLuint client_id) { 123 ShaderMap::iterator it = shaders_.find(client_id); 124 return it != shaders_.end() ? it->second.get() : NULL; 125 } 126 127 bool ShaderManager::GetClientId(GLuint service_id, GLuint* client_id) const { 128 // This doesn't need to be fast. It's only used during slow queries. 129 for (ShaderMap::const_iterator it = shaders_.begin(); 130 it != shaders_.end(); ++it) { 131 if (it->second->service_id() == service_id) { 132 *client_id = it->first; 133 return true; 134 } 135 } 136 return false; 137 } 138 139 bool ShaderManager::IsOwned(Shader* shader) { 140 for (ShaderMap::iterator it = shaders_.begin(); 141 it != shaders_.end(); ++it) { 142 if (it->second.get() == shader) { 143 return true; 144 } 145 } 146 return false; 147 } 148 149 void ShaderManager::RemoveShader(Shader* shader) { 150 DCHECK(shader); 151 DCHECK(IsOwned(shader)); 152 if (shader->IsDeleted() && !shader->InUse()) { 153 for (ShaderMap::iterator it = shaders_.begin(); 154 it != shaders_.end(); ++it) { 155 if (it->second.get() == shader) { 156 shaders_.erase(it); 157 return; 158 } 159 } 160 NOTREACHED(); 161 } 162 } 163 164 void ShaderManager::MarkAsDeleted(Shader* shader) { 165 DCHECK(shader); 166 DCHECK(IsOwned(shader)); 167 shader->MarkAsDeleted(); 168 RemoveShader(shader); 169 } 170 171 void ShaderManager::UseShader(Shader* shader) { 172 DCHECK(shader); 173 DCHECK(IsOwned(shader)); 174 shader->IncUseCount(); 175 } 176 177 void ShaderManager::UnuseShader(Shader* shader) { 178 DCHECK(shader); 179 DCHECK(IsOwned(shader)); 180 shader->DecUseCount(); 181 RemoveShader(shader); 182 } 183 184 } // namespace gles2 185 } // namespace gpu 186 187 188