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
Shader(GLuint service_id,GLenum shader_type)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
~Shader()22 Shader::~Shader() {
23 }
24
IncUseCount()25 void Shader::IncUseCount() {
26 ++use_count_;
27 }
28
DecUseCount()29 void Shader::DecUseCount() {
30 --use_count_;
31 DCHECK_GE(use_count_, 0);
32 }
33
MarkAsDeleted()34 void Shader::MarkAsDeleted() {
35 DCHECK_NE(service_id_, 0u);
36 service_id_ = 0;
37 }
38
SetStatus(bool valid,const char * log,ShaderTranslatorInterface * translator)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*
GetAttribInfo(const std::string & name) const62 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
GetAttribMappedName(const std::string & original_name) const68 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
GetOriginalNameFromHashedName(const std::string & hashed_name) const78 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*
GetUniformInfo(const std::string & name) const87 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
ShaderManager()93 ShaderManager::ShaderManager() {}
94
~ShaderManager()95 ShaderManager::~ShaderManager() {
96 DCHECK(shaders_.empty());
97 }
98
Destroy(bool have_context)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
CreateShader(GLuint client_id,GLuint service_id,GLenum shader_type)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
GetShader(GLuint client_id)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
GetClientId(GLuint service_id,GLuint * client_id) const129 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
IsOwned(Shader * shader)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
RemoveShader(Shader * shader)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
MarkAsDeleted(Shader * shader)166 void ShaderManager::MarkAsDeleted(Shader* shader) {
167 DCHECK(shader);
168 DCHECK(IsOwned(shader));
169 shader->MarkAsDeleted();
170 RemoveShader(shader);
171 }
172
UseShader(Shader * shader)173 void ShaderManager::UseShader(Shader* shader) {
174 DCHECK(shader);
175 DCHECK(IsOwned(shader));
176 shader->IncUseCount();
177 }
178
UnuseShader(Shader * shader)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