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 12namespace gpu { 13namespace gles2 { 14 15Shader::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 22Shader::~Shader() { 23} 24 25void Shader::IncUseCount() { 26 ++use_count_; 27} 28 29void Shader::DecUseCount() { 30 --use_count_; 31 DCHECK_GE(use_count_, 0); 32} 33 34void Shader::MarkAsDeleted() { 35 DCHECK_NE(service_id_, 0u); 36 service_id_ = 0; 37} 38 39void 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 61const 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 68const 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 78const 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 86const 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 93ShaderManager::ShaderManager() {} 94 95ShaderManager::~ShaderManager() { 96 DCHECK(shaders_.empty()); 97} 98 99void 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 112Shader* 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 124Shader* ShaderManager::GetShader(GLuint client_id) { 125 ShaderMap::iterator it = shaders_.find(client_id); 126 return it != shaders_.end() ? it->second.get() : NULL; 127} 128 129bool 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 141bool 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 151void 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 166void ShaderManager::MarkAsDeleted(Shader* shader) { 167 DCHECK(shader); 168 DCHECK(IsOwned(shader)); 169 shader->MarkAsDeleted(); 170 RemoveShader(shader); 171} 172 173void ShaderManager::UseShader(Shader* shader) { 174 DCHECK(shader); 175 DCHECK(IsOwned(shader)); 176 shader->IncUseCount(); 177} 178 179void 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