OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <set> | 8 #include <set> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 index = index * 10 + digit; | 89 index = index * 10 + digit; |
90 } | 90 } |
91 | 91 |
92 *element_index = index; | 92 *element_index = index; |
93 *new_name = name.substr(0, open_pos); | 93 *new_name = name.substr(0, open_pos); |
94 return true; | 94 return true; |
95 } | 95 } |
96 | 96 |
97 } // anonymous namespace. | 97 } // anonymous namespace. |
98 | 98 |
99 ProgramManager::ProgramInfo::UniformInfo::UniformInfo() | 99 Program::UniformInfo::UniformInfo() |
100 : size(0), | 100 : size(0), |
101 type(GL_NONE), | 101 type(GL_NONE), |
102 fake_location_base(0), | 102 fake_location_base(0), |
103 is_array(false) { | 103 is_array(false) { |
104 } | 104 } |
105 | 105 |
106 ProgramManager::ProgramInfo::UniformInfo::UniformInfo( | 106 Program::UniformInfo::UniformInfo( |
107 GLsizei _size, | 107 GLsizei _size, |
108 GLenum _type, | 108 GLenum _type, |
109 int _fake_location_base, | 109 int _fake_location_base, |
110 const std::string& _name) | 110 const std::string& _name) |
111 : size(_size), | 111 : size(_size), |
112 type(_type), | 112 type(_type), |
113 fake_location_base(_fake_location_base), | 113 fake_location_base(_fake_location_base), |
114 is_array(false), | 114 is_array(false), |
115 name(_name) { | 115 name(_name) { |
116 } | 116 } |
117 | 117 |
118 ProgramManager::ProgramInfo::UniformInfo::~UniformInfo() {} | 118 Program::UniformInfo::~UniformInfo() {} |
119 | 119 |
120 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { | 120 bool ProgramManager::IsInvalidPrefix(const char* name, size_t length) { |
121 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; | 121 static const char kInvalidPrefix[] = { 'g', 'l', '_' }; |
122 return (length >= sizeof(kInvalidPrefix) && | 122 return (length >= sizeof(kInvalidPrefix) && |
123 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); | 123 memcmp(name, kInvalidPrefix, sizeof(kInvalidPrefix)) == 0); |
124 } | 124 } |
125 | 125 |
126 ProgramManager::ProgramInfo::ProgramInfo( | 126 Program::Program( |
127 ProgramManager* manager, GLuint service_id) | 127 ProgramManager* manager, GLuint service_id) |
128 : manager_(manager), | 128 : manager_(manager), |
129 use_count_(0), | 129 use_count_(0), |
130 max_attrib_name_length_(0), | 130 max_attrib_name_length_(0), |
131 max_uniform_name_length_(0), | 131 max_uniform_name_length_(0), |
132 service_id_(service_id), | 132 service_id_(service_id), |
133 deleted_(false), | 133 deleted_(false), |
134 valid_(false), | 134 valid_(false), |
135 link_status_(false), | 135 link_status_(false), |
136 uniforms_cleared_(false), | 136 uniforms_cleared_(false), |
137 num_uniforms_(0) { | 137 num_uniforms_(0) { |
138 manager_->StartTracking(this); | 138 manager_->StartTracking(this); |
139 } | 139 } |
140 | 140 |
141 void ProgramManager::ProgramInfo::Reset() { | 141 void Program::Reset() { |
142 valid_ = false; | 142 valid_ = false; |
143 link_status_ = false; | 143 link_status_ = false; |
144 num_uniforms_ = 0; | 144 num_uniforms_ = 0; |
145 max_uniform_name_length_ = 0; | 145 max_uniform_name_length_ = 0; |
146 max_attrib_name_length_ = 0; | 146 max_attrib_name_length_ = 0; |
147 attrib_infos_.clear(); | 147 attrib_infos_.clear(); |
148 uniform_infos_.clear(); | 148 uniform_infos_.clear(); |
149 sampler_indices_.clear(); | 149 sampler_indices_.clear(); |
150 attrib_location_to_index_map_.clear(); | 150 attrib_location_to_index_map_.clear(); |
151 } | 151 } |
152 | 152 |
153 std::string ProgramManager::ProgramInfo::ProcessLogInfo( | 153 std::string Program::ProcessLogInfo( |
154 const std::string& log) { | 154 const std::string& log) { |
155 std::string output; | 155 std::string output; |
156 re2::StringPiece input(log); | 156 re2::StringPiece input(log); |
157 std::string prior_log; | 157 std::string prior_log; |
158 std::string hashed_name; | 158 std::string hashed_name; |
159 while (RE2::Consume(&input, | 159 while (RE2::Consume(&input, |
160 "(.*)(webgl_[0123456789abcdefABCDEF]+)", | 160 "(.*)(webgl_[0123456789abcdefABCDEF]+)", |
161 &prior_log, | 161 &prior_log, |
162 &hashed_name)) { | 162 &hashed_name)) { |
163 output += prior_log; | 163 output += prior_log; |
164 | 164 |
165 const std::string* original_name = | 165 const std::string* original_name = |
166 GetOriginalNameFromHashedName(hashed_name); | 166 GetOriginalNameFromHashedName(hashed_name); |
167 if (original_name) | 167 if (original_name) |
168 output += *original_name; | 168 output += *original_name; |
169 else | 169 else |
170 output += hashed_name; | 170 output += hashed_name; |
171 } | 171 } |
172 | 172 |
173 return output + input.as_string(); | 173 return output + input.as_string(); |
174 } | 174 } |
175 | 175 |
176 void ProgramManager::ProgramInfo::UpdateLogInfo() { | 176 void Program::UpdateLogInfo() { |
177 GLint max_len = 0; | 177 GLint max_len = 0; |
178 glGetProgramiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); | 178 glGetProgramiv(service_id_, GL_INFO_LOG_LENGTH, &max_len); |
179 if (max_len == 0) { | 179 if (max_len == 0) { |
180 set_log_info(NULL); | 180 set_log_info(NULL); |
181 return; | 181 return; |
182 } | 182 } |
183 scoped_array<char> temp(new char[max_len]); | 183 scoped_array<char> temp(new char[max_len]); |
184 GLint len = 0; | 184 GLint len = 0; |
185 glGetProgramInfoLog(service_id_, max_len, &len, temp.get()); | 185 glGetProgramInfoLog(service_id_, max_len, &len, temp.get()); |
186 DCHECK(max_len == 0 || len < max_len); | 186 DCHECK(max_len == 0 || len < max_len); |
187 DCHECK(len == 0 || temp[len] == '\0'); | 187 DCHECK(len == 0 || temp[len] == '\0'); |
188 std::string log(temp.get(), len); | 188 std::string log(temp.get(), len); |
189 set_log_info(ProcessLogInfo(log).c_str()); | 189 set_log_info(ProcessLogInfo(log).c_str()); |
190 } | 190 } |
191 | 191 |
192 void ProgramManager::ProgramInfo::ClearUniforms( | 192 void Program::ClearUniforms( |
193 std::vector<uint8>* zero_buffer) { | 193 std::vector<uint8>* zero_buffer) { |
194 DCHECK(zero_buffer); | 194 DCHECK(zero_buffer); |
195 if (uniforms_cleared_) { | 195 if (uniforms_cleared_) { |
196 return; | 196 return; |
197 } | 197 } |
198 uniforms_cleared_ = true; | 198 uniforms_cleared_ = true; |
199 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 199 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { |
200 const UniformInfo& uniform_info = uniform_infos_[ii]; | 200 const UniformInfo& uniform_info = uniform_infos_[ii]; |
201 if (!uniform_info.IsValid()) { | 201 if (!uniform_info.IsValid()) { |
202 continue; | 202 continue; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 }; | 278 }; |
279 | 279 |
280 struct UniformDataComparer { | 280 struct UniformDataComparer { |
281 bool operator()(const UniformData& lhs, const UniformData& rhs) const { | 281 bool operator()(const UniformData& lhs, const UniformData& rhs) const { |
282 return lhs.queried_name < rhs.queried_name; | 282 return lhs.queried_name < rhs.queried_name; |
283 } | 283 } |
284 }; | 284 }; |
285 | 285 |
286 } // anonymous namespace | 286 } // anonymous namespace |
287 | 287 |
288 void ProgramManager::ProgramInfo::Update() { | 288 void Program::Update() { |
289 Reset(); | 289 Reset(); |
290 UpdateLogInfo(); | 290 UpdateLogInfo(); |
291 link_status_ = true; | 291 link_status_ = true; |
292 uniforms_cleared_ = false; | 292 uniforms_cleared_ = false; |
293 GLint num_attribs = 0; | 293 GLint num_attribs = 0; |
294 GLint max_len = 0; | 294 GLint max_len = 0; |
295 GLint max_location = -1; | 295 GLint max_location = -1; |
296 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); | 296 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTES, &num_attribs); |
297 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); | 297 glGetProgramiv(service_id_, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); |
298 // TODO(gman): Should we check for error? | 298 // TODO(gman): Should we check for error? |
299 scoped_array<char> name_buffer(new char[max_len]); | 299 scoped_array<char> name_buffer(new char[max_len]); |
300 for (GLint ii = 0; ii < num_attribs; ++ii) { | 300 for (GLint ii = 0; ii < num_attribs; ++ii) { |
301 GLsizei length = 0; | 301 GLsizei length = 0; |
302 GLsizei size = 0; | 302 GLsizei size = 0; |
303 GLenum type = 0; | 303 GLenum type = 0; |
304 glGetActiveAttrib( | 304 glGetActiveAttrib( |
305 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); | 305 service_id_, ii, max_len, &length, &size, &type, name_buffer.get()); |
306 DCHECK(max_len == 0 || length < max_len); | 306 DCHECK(max_len == 0 || length < max_len); |
307 DCHECK(length == 0 || name_buffer[length] == '\0'); | 307 DCHECK(length == 0 || name_buffer[length] == '\0'); |
308 if (!IsInvalidPrefix(name_buffer.get(), length)) { | 308 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { |
309 std::string name; | 309 std::string name; |
310 std::string original_name; | 310 std::string original_name; |
311 GetCorrectedVariableInfo( | 311 GetCorrectedVariableInfo( |
312 false, name_buffer.get(), &name, &original_name, &size, &type); | 312 false, name_buffer.get(), &name, &original_name, &size, &type); |
313 // TODO(gman): Should we check for error? | 313 // TODO(gman): Should we check for error? |
314 GLint location = glGetAttribLocation(service_id_, name_buffer.get()); | 314 GLint location = glGetAttribLocation(service_id_, name_buffer.get()); |
315 if (location > max_location) { | 315 if (location > max_location) { |
316 max_location = location; | 316 max_location = location; |
317 } | 317 } |
318 attrib_infos_.push_back( | 318 attrib_infos_.push_back( |
319 VertexAttribInfo(size, type, original_name, location)); | 319 VertexAttrib(size, type, original_name, location)); |
320 max_attrib_name_length_ = std::max( | 320 max_attrib_name_length_ = std::max( |
321 max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); | 321 max_attrib_name_length_, static_cast<GLsizei>(original_name.size())); |
322 } | 322 } |
323 } | 323 } |
324 | 324 |
325 // Create attrib location to index map. | 325 // Create attrib location to index map. |
326 attrib_location_to_index_map_.resize(max_location + 1); | 326 attrib_location_to_index_map_.resize(max_location + 1); |
327 for (GLint ii = 0; ii <= max_location; ++ii) { | 327 for (GLint ii = 0; ii <= max_location; ++ii) { |
328 attrib_location_to_index_map_[ii] = -1; | 328 attrib_location_to_index_map_[ii] = -1; |
329 } | 329 } |
330 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 330 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
331 const VertexAttribInfo& info = attrib_infos_[ii]; | 331 const VertexAttrib& info = attrib_infos_[ii]; |
332 attrib_location_to_index_map_[info.location] = ii; | 332 attrib_location_to_index_map_[info.location] = ii; |
333 } | 333 } |
334 | 334 |
335 #if !defined(NDEBUG) | 335 #if !defined(NDEBUG) |
336 if (CommandLine::ForCurrentProcess()->HasSwitch( | 336 if (CommandLine::ForCurrentProcess()->HasSwitch( |
337 switches::kEnableGPUServiceLoggingGPU)) { | 337 switches::kEnableGPUServiceLoggingGPU)) { |
338 DLOG(INFO) << "----: attribs for service_id: " << service_id(); | 338 DLOG(INFO) << "----: attribs for service_id: " << service_id(); |
339 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 339 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
340 const VertexAttribInfo& info = attrib_infos_[ii]; | 340 const VertexAttrib& info = attrib_infos_[ii]; |
341 DLOG(INFO) << ii << ": loc = " << info.location | 341 DLOG(INFO) << ii << ": loc = " << info.location |
342 << ", size = " << info.size | 342 << ", size = " << info.size |
343 << ", type = " << GLES2Util::GetStringEnum(info.type) | 343 << ", type = " << GLES2Util::GetStringEnum(info.type) |
344 << ", name = " << info.name; | 344 << ", name = " << info.name; |
345 } | 345 } |
346 } | 346 } |
347 #endif | 347 #endif |
348 | 348 |
349 max_len = 0; | 349 max_len = 0; |
350 GLint num_uniforms = 0; | 350 GLint num_uniforms = 0; |
351 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); | 351 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORMS, &num_uniforms); |
352 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); | 352 glGetProgramiv(service_id_, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_len); |
353 name_buffer.reset(new char[max_len]); | 353 name_buffer.reset(new char[max_len]); |
354 | 354 |
355 // Reads all the names. | 355 // Reads all the names. |
356 std::vector<UniformData> uniform_data_; | 356 std::vector<UniformData> uniform_data_; |
357 for (GLint ii = 0; ii < num_uniforms; ++ii) { | 357 for (GLint ii = 0; ii < num_uniforms; ++ii) { |
358 GLsizei length = 0; | 358 GLsizei length = 0; |
359 UniformData data; | 359 UniformData data; |
360 glGetActiveUniform( | 360 glGetActiveUniform( |
361 service_id_, ii, max_len, &length, | 361 service_id_, ii, max_len, &length, |
362 &data.size, &data.type, name_buffer.get()); | 362 &data.size, &data.type, name_buffer.get()); |
363 DCHECK(max_len == 0 || length < max_len); | 363 DCHECK(max_len == 0 || length < max_len); |
364 DCHECK(length == 0 || name_buffer[length] == '\0'); | 364 DCHECK(length == 0 || name_buffer[length] == '\0'); |
365 if (!IsInvalidPrefix(name_buffer.get(), length)) { | 365 if (!ProgramManager::IsInvalidPrefix(name_buffer.get(), length)) { |
366 data.queried_name = std::string(name_buffer.get()); | 366 data.queried_name = std::string(name_buffer.get()); |
367 GetCorrectedVariableInfo( | 367 GetCorrectedVariableInfo( |
368 true, name_buffer.get(), &data.corrected_name, &data.original_name, | 368 true, name_buffer.get(), &data.corrected_name, &data.original_name, |
369 &data.size, &data.type); | 369 &data.size, &data.type); |
370 uniform_data_.push_back(data); | 370 uniform_data_.push_back(data); |
371 } | 371 } |
372 } | 372 } |
373 | 373 |
374 // NOTE: We don't care if 2 uniforms are bound to the same location. | 374 // NOTE: We don't care if 2 uniforms are bound to the same location. |
375 // One of them will take preference. The spec allows this, same as | 375 // One of them will take preference. The spec allows this, same as |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 << ", type = " << GLES2Util::GetStringEnum(info.type) | 422 << ", type = " << GLES2Util::GetStringEnum(info.type) |
423 << ", name = " << info.name; | 423 << ", name = " << info.name; |
424 } | 424 } |
425 } | 425 } |
426 } | 426 } |
427 #endif | 427 #endif |
428 | 428 |
429 valid_ = true; | 429 valid_ = true; |
430 } | 430 } |
431 | 431 |
432 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { | 432 void Program::ExecuteBindAttribLocationCalls() { |
433 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin(); | 433 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin(); |
434 it != bind_attrib_location_map_.end(); ++it) { | 434 it != bind_attrib_location_map_.end(); ++it) { |
435 const std::string* mapped_name = GetAttribMappedName(it->first); | 435 const std::string* mapped_name = GetAttribMappedName(it->first); |
436 if (mapped_name && *mapped_name != it->first) | 436 if (mapped_name && *mapped_name != it->first) |
437 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); | 437 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); |
438 } | 438 } |
439 } | 439 } |
440 | 440 |
441 void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info, | 441 void ProgramManager::DoCompileShader(Shader* info, |
442 ShaderTranslator* translator, | 442 ShaderTranslator* translator, |
443 FeatureInfo* feature_info) { | 443 FeatureInfo* feature_info) { |
444 TimeTicks before = TimeTicks::HighResNow(); | 444 TimeTicks before = TimeTicks::HighResNow(); |
445 if (program_cache_ && | 445 if (program_cache_ && |
446 program_cache_->GetShaderCompilationStatus(info->source() ? | 446 program_cache_->GetShaderCompilationStatus(info->source() ? |
447 *info->source() : "") == | 447 *info->source() : "") == |
448 ProgramCache::COMPILATION_SUCCEEDED) { | 448 ProgramCache::COMPILATION_SUCCEEDED) { |
449 info->SetStatus(true, "", translator); | 449 info->SetStatus(true, "", translator); |
450 info->FlagSourceAsCompiled(false); | 450 info->FlagSourceAsCompiled(false); |
451 UMA_HISTOGRAM_CUSTOM_COUNTS( | 451 UMA_HISTOGRAM_CUSTOM_COUNTS( |
452 "GPU.ProgramCache.CompilationCacheHitTime", | 452 "GPU.ProgramCache.CompilationCacheHitTime", |
453 (TimeTicks::HighResNow() - before).InMicroseconds(), | 453 (TimeTicks::HighResNow() - before).InMicroseconds(), |
454 0, | 454 0, |
455 TimeDelta::FromSeconds(1).InMicroseconds(), | 455 TimeDelta::FromSeconds(1).InMicroseconds(), |
456 50); | 456 50); |
457 return; | 457 return; |
458 } | 458 } |
459 ForceCompileShader(info->source(), info, translator, feature_info); | 459 ForceCompileShader(info->source(), info, translator, feature_info); |
460 UMA_HISTOGRAM_CUSTOM_COUNTS( | 460 UMA_HISTOGRAM_CUSTOM_COUNTS( |
461 "GPU.ProgramCache.CompilationCacheMissTime", | 461 "GPU.ProgramCache.CompilationCacheMissTime", |
462 (TimeTicks::HighResNow() - before).InMicroseconds(), | 462 (TimeTicks::HighResNow() - before).InMicroseconds(), |
463 0, | 463 0, |
464 TimeDelta::FromSeconds(1).InMicroseconds(), | 464 TimeDelta::FromSeconds(1).InMicroseconds(), |
465 50); | 465 50); |
466 } | 466 } |
467 | 467 |
468 void ProgramManager::ForceCompileShader(const std::string* source, | 468 void ProgramManager::ForceCompileShader(const std::string* source, |
469 ShaderManager::ShaderInfo* info, | 469 Shader* info, |
470 ShaderTranslator* translator, | 470 ShaderTranslator* translator, |
471 FeatureInfo* feature_info) { | 471 FeatureInfo* feature_info) { |
472 info->FlagSourceAsCompiled(true); | 472 info->FlagSourceAsCompiled(true); |
473 | 473 |
474 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to | 474 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to |
475 // glShaderSource and then glCompileShader. | 475 // glShaderSource and then glCompileShader. |
476 const char* shader_src = source ? source->c_str() : ""; | 476 const char* shader_src = source ? source->c_str() : ""; |
477 if (translator) { | 477 if (translator) { |
478 if (!translator->Translate(shader_src)) { | 478 if (!translator->Translate(shader_src)) { |
479 info->SetStatus(false, translator->info_log(), NULL); | 479 info->SetStatus(false, translator->info_log(), NULL); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 info->SetStatus(false, std::string(temp.get(), len).c_str(), NULL); | 522 info->SetStatus(false, std::string(temp.get(), len).c_str(), NULL); |
523 LOG_IF(ERROR, translator) | 523 LOG_IF(ERROR, translator) |
524 << "Shader translator allowed/produced an invalid shader " | 524 << "Shader translator allowed/produced an invalid shader " |
525 << "unless the driver is buggy:" | 525 << "unless the driver is buggy:" |
526 << "\n--original-shader--\n" << (source ? *source : "") | 526 << "\n--original-shader--\n" << (source ? *source : "") |
527 << "\n--translated-shader--\n" << shader_src | 527 << "\n--translated-shader--\n" << shader_src |
528 << "\n--info-log--\n" << *info->log_info(); | 528 << "\n--info-log--\n" << *info->log_info(); |
529 } | 529 } |
530 } | 530 } |
531 | 531 |
532 bool ProgramManager::ProgramInfo::Link(ShaderManager* manager, | 532 bool Program::Link(ShaderManager* manager, |
533 ShaderTranslator* vertex_translator, | 533 ShaderTranslator* vertex_translator, |
534 ShaderTranslator* fragment_translator, | 534 ShaderTranslator* fragment_translator, |
535 FeatureInfo* feature_info) { | 535 FeatureInfo* feature_info) { |
536 ClearLinkStatus(); | 536 ClearLinkStatus(); |
537 if (!CanLink()) { | 537 if (!CanLink()) { |
538 set_log_info("missing shaders"); | 538 set_log_info("missing shaders"); |
539 return false; | 539 return false; |
540 } | 540 } |
541 if (DetectAttribLocationBindingConflicts()) { | 541 if (DetectAttribLocationBindingConflicts()) { |
542 set_log_info("glBindAttribLocation() conflicts"); | 542 set_log_info("glBindAttribLocation() conflicts"); |
(...skipping 15 matching lines...) Expand all Loading... |
558 service_id(), | 558 service_id(), |
559 attached_shaders_[0], | 559 attached_shaders_[0], |
560 attached_shaders_[1], | 560 attached_shaders_[1], |
561 &bind_attrib_location_map_); | 561 &bind_attrib_location_map_); |
562 link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; | 562 link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; |
563 UMA_HISTOGRAM_BOOLEAN("GPU.ProgramCache.LoadBinarySuccess", !link); | 563 UMA_HISTOGRAM_BOOLEAN("GPU.ProgramCache.LoadBinarySuccess", !link); |
564 } | 564 } |
565 | 565 |
566 if (link) { | 566 if (link) { |
567 // compile our shaders if they're pending | 567 // compile our shaders if they're pending |
568 const int kShaders = ProgramManager::ProgramInfo::kMaxAttachedShaders; | 568 const int kShaders = Program::kMaxAttachedShaders; |
569 for (int i = 0; i < kShaders; ++i) { | 569 for (int i = 0; i < kShaders; ++i) { |
570 ShaderManager::ShaderInfo* info = attached_shaders_[i].get(); | 570 Shader* info = attached_shaders_[i].get(); |
571 if (info->compilation_status() == | 571 if (info->compilation_status() == |
572 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) { | 572 Shader::PENDING_DEFERRED_COMPILE) { |
573 ShaderTranslator* translator = ShaderIndexToTranslator( | 573 ShaderTranslator* translator = ShaderIndexToTranslator( |
574 i, | 574 i, |
575 vertex_translator, | 575 vertex_translator, |
576 fragment_translator); | 576 fragment_translator); |
577 manager_->ForceCompileShader(info->deferred_compilation_source(), | 577 manager_->ForceCompileShader(info->deferred_compilation_source(), |
578 attached_shaders_[i], | 578 attached_shaders_[i], |
579 translator, | 579 translator, |
580 feature_info); | 580 feature_info); |
581 CHECK(info->IsValid()); | 581 CHECK(info->IsValid()); |
582 } | 582 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 0, | 618 0, |
619 TimeDelta::FromSeconds(1).InMicroseconds(), | 619 TimeDelta::FromSeconds(1).InMicroseconds(), |
620 50); | 620 50); |
621 } | 621 } |
622 } else { | 622 } else { |
623 UpdateLogInfo(); | 623 UpdateLogInfo(); |
624 } | 624 } |
625 return success == GL_TRUE; | 625 return success == GL_TRUE; |
626 } | 626 } |
627 | 627 |
628 void ProgramManager::ProgramInfo::Validate() { | 628 void Program::Validate() { |
629 if (!IsValid()) { | 629 if (!IsValid()) { |
630 set_log_info("program not linked"); | 630 set_log_info("program not linked"); |
631 return; | 631 return; |
632 } | 632 } |
633 glValidateProgram(service_id()); | 633 glValidateProgram(service_id()); |
634 UpdateLogInfo(); | 634 UpdateLogInfo(); |
635 } | 635 } |
636 | 636 |
637 GLint ProgramManager::ProgramInfo::GetUniformFakeLocation( | 637 GLint Program::GetUniformFakeLocation( |
638 const std::string& name) const { | 638 const std::string& name) const { |
639 bool getting_array_location = false; | 639 bool getting_array_location = false; |
640 size_t open_pos = std::string::npos; | 640 size_t open_pos = std::string::npos; |
641 int index = 0; | 641 int index = 0; |
642 if (!GLES2Util::ParseUniformName( | 642 if (!GLES2Util::ParseUniformName( |
643 name, &open_pos, &index, &getting_array_location)) { | 643 name, &open_pos, &index, &getting_array_location)) { |
644 return -1; | 644 return -1; |
645 } | 645 } |
646 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { | 646 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) { |
647 const UniformInfo& info = uniform_infos_[ii]; | 647 const UniformInfo& info = uniform_infos_[ii]; |
(...skipping 12 matching lines...) Expand all Loading... |
660 if (index >= 0 && index < info.size) { | 660 if (index >= 0 && index < info.size) { |
661 return ProgramManager::MakeFakeLocation( | 661 return ProgramManager::MakeFakeLocation( |
662 info.fake_location_base, index); | 662 info.fake_location_base, index); |
663 } | 663 } |
664 } | 664 } |
665 } | 665 } |
666 } | 666 } |
667 return -1; | 667 return -1; |
668 } | 668 } |
669 | 669 |
670 GLint ProgramManager::ProgramInfo::GetAttribLocation( | 670 GLint Program::GetAttribLocation( |
671 const std::string& name) const { | 671 const std::string& name) const { |
672 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { | 672 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) { |
673 const VertexAttribInfo& info = attrib_infos_[ii]; | 673 const VertexAttrib& info = attrib_infos_[ii]; |
674 if (info.name == name) { | 674 if (info.name == name) { |
675 return info.location; | 675 return info.location; |
676 } | 676 } |
677 } | 677 } |
678 return -1; | 678 return -1; |
679 } | 679 } |
680 | 680 |
681 const ProgramManager::ProgramInfo::UniformInfo* | 681 const Program::UniformInfo* |
682 ProgramManager::ProgramInfo::GetUniformInfoByFakeLocation( | 682 Program::GetUniformInfoByFakeLocation( |
683 GLint fake_location, GLint* real_location, GLint* array_index) const { | 683 GLint fake_location, GLint* real_location, GLint* array_index) const { |
684 DCHECK(real_location); | 684 DCHECK(real_location); |
685 DCHECK(array_index); | 685 DCHECK(array_index); |
686 if (fake_location < 0) { | 686 if (fake_location < 0) { |
687 return NULL; | 687 return NULL; |
688 } | 688 } |
689 | 689 |
690 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 690 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); |
691 if (uniform_index >= 0 && | 691 if (uniform_index >= 0 && |
692 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 692 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { |
693 const UniformInfo& uniform_info = uniform_infos_[uniform_index]; | 693 const UniformInfo& uniform_info = uniform_infos_[uniform_index]; |
694 if (!uniform_info.IsValid()) { | 694 if (!uniform_info.IsValid()) { |
695 return NULL; | 695 return NULL; |
696 } | 696 } |
697 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); | 697 GLint element_index = GetArrayElementIndexFromFakeLocation(fake_location); |
698 if (element_index < uniform_info.size) { | 698 if (element_index < uniform_info.size) { |
699 *real_location = uniform_info.element_locations[element_index]; | 699 *real_location = uniform_info.element_locations[element_index]; |
700 *array_index = element_index; | 700 *array_index = element_index; |
701 return &uniform_info; | 701 return &uniform_info; |
702 } | 702 } |
703 } | 703 } |
704 return NULL; | 704 return NULL; |
705 } | 705 } |
706 | 706 |
707 const std::string* ProgramManager::ProgramInfo::GetAttribMappedName( | 707 const std::string* Program::GetAttribMappedName( |
708 const std::string& original_name) const { | 708 const std::string& original_name) const { |
709 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 709 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
710 ShaderManager::ShaderInfo* shader_info = attached_shaders_[ii].get(); | 710 Shader* shader_info = attached_shaders_[ii].get(); |
711 if (shader_info) { | 711 if (shader_info) { |
712 const std::string* mapped_name = | 712 const std::string* mapped_name = |
713 shader_info->GetAttribMappedName(original_name); | 713 shader_info->GetAttribMappedName(original_name); |
714 if (mapped_name) | 714 if (mapped_name) |
715 return mapped_name; | 715 return mapped_name; |
716 } | 716 } |
717 } | 717 } |
718 return NULL; | 718 return NULL; |
719 } | 719 } |
720 | 720 |
721 const std::string* ProgramManager::ProgramInfo::GetOriginalNameFromHashedName( | 721 const std::string* Program::GetOriginalNameFromHashedName( |
722 const std::string& hashed_name) const { | 722 const std::string& hashed_name) const { |
723 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 723 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
724 ShaderManager::ShaderInfo* shader_info = attached_shaders_[ii].get(); | 724 Shader* shader_info = attached_shaders_[ii].get(); |
725 if (shader_info) { | 725 if (shader_info) { |
726 const std::string* original_name = | 726 const std::string* original_name = |
727 shader_info->GetOriginalNameFromHashedName(hashed_name); | 727 shader_info->GetOriginalNameFromHashedName(hashed_name); |
728 if (original_name) | 728 if (original_name) |
729 return original_name; | 729 return original_name; |
730 } | 730 } |
731 } | 731 } |
732 return NULL; | 732 return NULL; |
733 } | 733 } |
734 | 734 |
735 bool ProgramManager::ProgramInfo::SetUniformLocationBinding( | 735 bool Program::SetUniformLocationBinding( |
736 const std::string& name, GLint location) { | 736 const std::string& name, GLint location) { |
737 std::string short_name; | 737 std::string short_name; |
738 int element_index = 0; | 738 int element_index = 0; |
739 if (!GetUniformNameSansElement(name, &element_index, &short_name) || | 739 if (!GetUniformNameSansElement(name, &element_index, &short_name) || |
740 element_index != 0) { | 740 element_index != 0) { |
741 return false; | 741 return false; |
742 } | 742 } |
743 | 743 |
744 bind_uniform_location_map_[short_name] = location; | 744 bind_uniform_location_map_[short_name] = location; |
745 return true; | 745 return true; |
746 } | 746 } |
747 | 747 |
748 // Note: This is only valid to call right after a program has been linked | 748 // Note: This is only valid to call right after a program has been linked |
749 // successfully. | 749 // successfully. |
750 void ProgramManager::ProgramInfo::GetCorrectedVariableInfo( | 750 void Program::GetCorrectedVariableInfo( |
751 bool use_uniforms, | 751 bool use_uniforms, |
752 const std::string& name, std::string* corrected_name, | 752 const std::string& name, std::string* corrected_name, |
753 std::string* original_name, | 753 std::string* original_name, |
754 GLsizei* size, GLenum* type) const { | 754 GLsizei* size, GLenum* type) const { |
755 DCHECK(corrected_name); | 755 DCHECK(corrected_name); |
756 DCHECK(original_name); | 756 DCHECK(original_name); |
757 DCHECK(size); | 757 DCHECK(size); |
758 DCHECK(type); | 758 DCHECK(type); |
759 const char* kArraySpec = "[0]"; | 759 const char* kArraySpec = "[0]"; |
760 for (int jj = 0; jj < 2; ++jj) { | 760 for (int jj = 0; jj < 2; ++jj) { |
761 std::string test_name(name + ((jj == 1) ? kArraySpec : "")); | 761 std::string test_name(name + ((jj == 1) ? kArraySpec : "")); |
762 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 762 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
763 ShaderManager::ShaderInfo* shader_info = attached_shaders_[ii].get(); | 763 Shader* shader_info = attached_shaders_[ii].get(); |
764 if (shader_info) { | 764 if (shader_info) { |
765 const ShaderManager::ShaderInfo::VariableInfo* variable_info = | 765 const Shader::VariableInfo* variable_info = |
766 use_uniforms ? shader_info->GetUniformInfo(test_name) : | 766 use_uniforms ? shader_info->GetUniformInfo(test_name) : |
767 shader_info->GetAttribInfo(test_name); | 767 shader_info->GetAttribInfo(test_name); |
768 // Note: There is an assuption here that if an attrib is defined in more | 768 // Note: There is an assuption here that if an attrib is defined in more |
769 // than 1 attached shader their types and sizes match. Should we check | 769 // than 1 attached shader their types and sizes match. Should we check |
770 // for that case? | 770 // for that case? |
771 if (variable_info) { | 771 if (variable_info) { |
772 *corrected_name = test_name; | 772 *corrected_name = test_name; |
773 *original_name = variable_info->name; | 773 *original_name = variable_info->name; |
774 *type = variable_info->type; | 774 *type = variable_info->type; |
775 *size = variable_info->size; | 775 *size = variable_info->size; |
776 return; | 776 return; |
777 } | 777 } |
778 } | 778 } |
779 } | 779 } |
780 } | 780 } |
781 *corrected_name = name; | 781 *corrected_name = name; |
782 *original_name = name; | 782 *original_name = name; |
783 } | 783 } |
784 | 784 |
785 bool ProgramManager::ProgramInfo::AddUniformInfo( | 785 bool Program::AddUniformInfo( |
786 GLsizei size, GLenum type, GLint location, GLint fake_base_location, | 786 GLsizei size, GLenum type, GLint location, GLint fake_base_location, |
787 const std::string& name, const std::string& original_name, | 787 const std::string& name, const std::string& original_name, |
788 size_t* next_available_index) { | 788 size_t* next_available_index) { |
789 DCHECK(next_available_index); | 789 DCHECK(next_available_index); |
790 const char* kArraySpec = "[0]"; | 790 const char* kArraySpec = "[0]"; |
791 size_t uniform_index = | 791 size_t uniform_index = |
792 fake_base_location >= 0 ? fake_base_location : *next_available_index; | 792 fake_base_location >= 0 ? fake_base_location : *next_available_index; |
793 if (uniform_infos_.size() < uniform_index + 1) { | 793 if (uniform_infos_.size() < uniform_index + 1) { |
794 uniform_infos_.resize(uniform_index + 1); | 794 uniform_infos_.resize(uniform_index + 1); |
795 } | 795 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 static_cast<GLsizei>(info.name.size())); | 845 static_cast<GLsizei>(info.name.size())); |
846 | 846 |
847 while (*next_available_index < uniform_infos_.size() && | 847 while (*next_available_index < uniform_infos_.size() && |
848 uniform_infos_[*next_available_index].IsValid()) { | 848 uniform_infos_[*next_available_index].IsValid()) { |
849 *next_available_index = *next_available_index + 1; | 849 *next_available_index = *next_available_index + 1; |
850 } | 850 } |
851 | 851 |
852 return true; | 852 return true; |
853 } | 853 } |
854 | 854 |
855 const ProgramManager::ProgramInfo::UniformInfo* | 855 const Program::UniformInfo* |
856 ProgramManager::ProgramInfo::GetUniformInfo( | 856 Program::GetUniformInfo( |
857 GLint index) const { | 857 GLint index) const { |
858 if (static_cast<size_t>(index) >= uniform_infos_.size()) { | 858 if (static_cast<size_t>(index) >= uniform_infos_.size()) { |
859 return NULL; | 859 return NULL; |
860 } | 860 } |
861 | 861 |
862 const UniformInfo& info = uniform_infos_[index]; | 862 const UniformInfo& info = uniform_infos_[index]; |
863 return info.IsValid() ? &info : NULL; | 863 return info.IsValid() ? &info : NULL; |
864 } | 864 } |
865 | 865 |
866 bool ProgramManager::ProgramInfo::SetSamplers( | 866 bool Program::SetSamplers( |
867 GLint num_texture_units, GLint fake_location, | 867 GLint num_texture_units, GLint fake_location, |
868 GLsizei count, const GLint* value) { | 868 GLsizei count, const GLint* value) { |
869 if (fake_location < 0) { | 869 if (fake_location < 0) { |
870 return true; | 870 return true; |
871 } | 871 } |
872 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); | 872 GLint uniform_index = GetUniformInfoIndexFromFakeLocation(fake_location); |
873 if (uniform_index >= 0 && | 873 if (uniform_index >= 0 && |
874 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { | 874 static_cast<size_t>(uniform_index) < uniform_infos_.size()) { |
875 UniformInfo& info = uniform_infos_[uniform_index]; | 875 UniformInfo& info = uniform_infos_[uniform_index]; |
876 if (!info.IsValid()) { | 876 if (!info.IsValid()) { |
(...skipping 10 matching lines...) Expand all Loading... |
887 } | 887 } |
888 std::copy(value, value + count, | 888 std::copy(value, value + count, |
889 info.texture_units.begin() + element_index); | 889 info.texture_units.begin() + element_index); |
890 return true; | 890 return true; |
891 } | 891 } |
892 } | 892 } |
893 } | 893 } |
894 return true; | 894 return true; |
895 } | 895 } |
896 | 896 |
897 void ProgramManager::ProgramInfo::GetProgramiv(GLenum pname, GLint* params) { | 897 void Program::GetProgramiv(GLenum pname, GLint* params) { |
898 switch (pname) { | 898 switch (pname) { |
899 case GL_ACTIVE_ATTRIBUTES: | 899 case GL_ACTIVE_ATTRIBUTES: |
900 *params = attrib_infos_.size(); | 900 *params = attrib_infos_.size(); |
901 break; | 901 break; |
902 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 902 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
903 // Notice +1 to accomodate NULL terminator. | 903 // Notice +1 to accomodate NULL terminator. |
904 *params = max_attrib_name_length_ + 1; | 904 *params = max_attrib_name_length_ + 1; |
905 break; | 905 break; |
906 case GL_ACTIVE_UNIFORMS: | 906 case GL_ACTIVE_UNIFORMS: |
907 *params = num_uniforms_; | 907 *params = num_uniforms_; |
(...skipping 18 matching lines...) Expand all Loading... |
926 } else { | 926 } else { |
927 glGetProgramiv(service_id_, pname, params); | 927 glGetProgramiv(service_id_, pname, params); |
928 } | 928 } |
929 break; | 929 break; |
930 default: | 930 default: |
931 glGetProgramiv(service_id_, pname, params); | 931 glGetProgramiv(service_id_, pname, params); |
932 break; | 932 break; |
933 } | 933 } |
934 } | 934 } |
935 | 935 |
936 bool ProgramManager::ProgramInfo::AttachShader( | 936 bool Program::AttachShader( |
937 ShaderManager* shader_manager, | 937 ShaderManager* shader_manager, |
938 ShaderManager::ShaderInfo* info) { | 938 Shader* info) { |
939 DCHECK(shader_manager); | 939 DCHECK(shader_manager); |
940 DCHECK(info); | 940 DCHECK(info); |
941 int index = ShaderTypeToIndex(info->shader_type()); | 941 int index = ShaderTypeToIndex(info->shader_type()); |
942 if (attached_shaders_[index] != NULL) { | 942 if (attached_shaders_[index] != NULL) { |
943 return false; | 943 return false; |
944 } | 944 } |
945 attached_shaders_[index] = ShaderManager::ShaderInfo::Ref(info); | 945 attached_shaders_[index] = scoped_refptr<Shader>(info); |
946 shader_manager->UseShader(info); | 946 shader_manager->UseShader(info); |
947 return true; | 947 return true; |
948 } | 948 } |
949 | 949 |
950 bool ProgramManager::ProgramInfo::DetachShader( | 950 bool Program::DetachShader( |
951 ShaderManager* shader_manager, | 951 ShaderManager* shader_manager, |
952 ShaderManager::ShaderInfo* info) { | 952 Shader* info) { |
953 DCHECK(shader_manager); | 953 DCHECK(shader_manager); |
954 DCHECK(info); | 954 DCHECK(info); |
955 if (attached_shaders_[ShaderTypeToIndex(info->shader_type())].get() != info) { | 955 if (attached_shaders_[ShaderTypeToIndex(info->shader_type())].get() != info) { |
956 return false; | 956 return false; |
957 } | 957 } |
958 attached_shaders_[ShaderTypeToIndex(info->shader_type())] = NULL; | 958 attached_shaders_[ShaderTypeToIndex(info->shader_type())] = NULL; |
959 shader_manager->UnuseShader(info); | 959 shader_manager->UnuseShader(info); |
960 return true; | 960 return true; |
961 } | 961 } |
962 | 962 |
963 void ProgramManager::ProgramInfo::DetachShaders(ShaderManager* shader_manager) { | 963 void Program::DetachShaders(ShaderManager* shader_manager) { |
964 DCHECK(shader_manager); | 964 DCHECK(shader_manager); |
965 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 965 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
966 if (attached_shaders_[ii]) { | 966 if (attached_shaders_[ii]) { |
967 DetachShader(shader_manager, attached_shaders_[ii]); | 967 DetachShader(shader_manager, attached_shaders_[ii]); |
968 } | 968 } |
969 } | 969 } |
970 } | 970 } |
971 | 971 |
972 bool ProgramManager::ProgramInfo::CanLink() const { | 972 bool Program::CanLink() const { |
973 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 973 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
974 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) { | 974 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) { |
975 return false; | 975 return false; |
976 } | 976 } |
977 } | 977 } |
978 return true; | 978 return true; |
979 } | 979 } |
980 | 980 |
981 bool ProgramManager::ProgramInfo::DetectAttribLocationBindingConflicts() const { | 981 bool Program::DetectAttribLocationBindingConflicts() const { |
982 std::set<GLint> location_binding_used; | 982 std::set<GLint> location_binding_used; |
983 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin(); | 983 for (LocationMap::const_iterator it = bind_attrib_location_map_.begin(); |
984 it != bind_attrib_location_map_.end(); ++it) { | 984 it != bind_attrib_location_map_.end(); ++it) { |
985 // Find out if an attribute is declared in this program's shaders. | 985 // Find out if an attribute is declared in this program's shaders. |
986 bool active = false; | 986 bool active = false; |
987 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { | 987 for (int ii = 0; ii < kMaxAttachedShaders; ++ii) { |
988 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) | 988 if (!attached_shaders_[ii] || !attached_shaders_[ii]->IsValid()) |
989 continue; | 989 continue; |
990 if (attached_shaders_[ii]->GetAttribInfo(it->first)) { | 990 if (attached_shaders_[ii]->GetAttribInfo(it->first)) { |
991 active = true; | 991 active = true; |
992 break; | 992 break; |
993 } | 993 } |
994 } | 994 } |
995 if (active) { | 995 if (active) { |
996 std::pair<std::set<GLint>::iterator, bool> result = | 996 std::pair<std::set<GLint>::iterator, bool> result = |
997 location_binding_used.insert(it->second); | 997 location_binding_used.insert(it->second); |
998 if (!result.second) | 998 if (!result.second) |
999 return true; | 999 return true; |
1000 } | 1000 } |
1001 } | 1001 } |
1002 return false; | 1002 return false; |
1003 } | 1003 } |
1004 | 1004 |
1005 static uint32 ComputeOffset(const void* start, const void* position) { | 1005 static uint32 ComputeOffset(const void* start, const void* position) { |
1006 return static_cast<const uint8*>(position) - | 1006 return static_cast<const uint8*>(position) - |
1007 static_cast<const uint8*>(start); | 1007 static_cast<const uint8*>(start); |
1008 } | 1008 } |
1009 | 1009 |
1010 void ProgramManager::ProgramInfo::GetProgramInfo( | 1010 void Program::GetProgram( |
1011 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { | 1011 ProgramManager* manager, CommonDecoder::Bucket* bucket) const { |
1012 // NOTE: It seems to me the math in here does not need check for overflow | 1012 // NOTE: It seems to me the math in here does not need check for overflow |
1013 // because the data being calucated from has various small limits. The max | 1013 // because the data being calucated from has various small limits. The max |
1014 // number of attribs + uniforms is somewhere well under 1024. The maximum size | 1014 // number of attribs + uniforms is somewhere well under 1024. The maximum size |
1015 // of an identifier is 256 characters. | 1015 // of an identifier is 256 characters. |
1016 uint32 num_locations = 0; | 1016 uint32 num_locations = 0; |
1017 uint32 total_string_size = 0; | 1017 uint32 total_string_size = 0; |
1018 | 1018 |
1019 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1019 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1020 const VertexAttribInfo& info = attrib_infos_[ii]; | 1020 const VertexAttrib& info = attrib_infos_[ii]; |
1021 num_locations += 1; | 1021 num_locations += 1; |
1022 total_string_size += info.name.size(); | 1022 total_string_size += info.name.size(); |
1023 } | 1023 } |
1024 | 1024 |
1025 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { | 1025 for (size_t ii = 0; ii < uniform_infos_.size(); ++ii) { |
1026 const UniformInfo& info = uniform_infos_[ii]; | 1026 const UniformInfo& info = uniform_infos_[ii]; |
1027 if (info.IsValid()) { | 1027 if (info.IsValid()) { |
1028 num_locations += info.element_locations.size(); | 1028 num_locations += info.element_locations.size(); |
1029 total_string_size += info.name.size(); | 1029 total_string_size += info.name.size(); |
1030 } | 1030 } |
(...skipping 17 matching lines...) Expand all Loading... |
1048 DCHECK(header); | 1048 DCHECK(header); |
1049 DCHECK(inputs); | 1049 DCHECK(inputs); |
1050 DCHECK(locations); | 1050 DCHECK(locations); |
1051 DCHECK(strings); | 1051 DCHECK(strings); |
1052 | 1052 |
1053 header->link_status = link_status_; | 1053 header->link_status = link_status_; |
1054 header->num_attribs = attrib_infos_.size(); | 1054 header->num_attribs = attrib_infos_.size(); |
1055 header->num_uniforms = num_uniforms_; | 1055 header->num_uniforms = num_uniforms_; |
1056 | 1056 |
1057 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { | 1057 for (size_t ii = 0; ii < attrib_infos_.size(); ++ii) { |
1058 const VertexAttribInfo& info = attrib_infos_[ii]; | 1058 const VertexAttrib& info = attrib_infos_[ii]; |
1059 inputs->size = info.size; | 1059 inputs->size = info.size; |
1060 inputs->type = info.type; | 1060 inputs->type = info.type; |
1061 inputs->location_offset = ComputeOffset(header, locations); | 1061 inputs->location_offset = ComputeOffset(header, locations); |
1062 inputs->name_offset = ComputeOffset(header, strings); | 1062 inputs->name_offset = ComputeOffset(header, strings); |
1063 inputs->name_length = info.name.size(); | 1063 inputs->name_length = info.name.size(); |
1064 *locations++ = info.location; | 1064 *locations++ = info.location; |
1065 memcpy(strings, info.name.c_str(), info.name.size()); | 1065 memcpy(strings, info.name.c_str(), info.name.size()); |
1066 strings += info.name.size(); | 1066 strings += info.name.size(); |
1067 ++inputs; | 1067 ++inputs; |
1068 } | 1068 } |
(...skipping 12 matching lines...) Expand all Loading... |
1081 } | 1081 } |
1082 memcpy(strings, info.name.c_str(), info.name.size()); | 1082 memcpy(strings, info.name.c_str(), info.name.size()); |
1083 strings += info.name.size(); | 1083 strings += info.name.size(); |
1084 ++inputs; | 1084 ++inputs; |
1085 } | 1085 } |
1086 } | 1086 } |
1087 | 1087 |
1088 DCHECK_EQ(ComputeOffset(header, strings), size); | 1088 DCHECK_EQ(ComputeOffset(header, strings), size); |
1089 } | 1089 } |
1090 | 1090 |
1091 ProgramManager::ProgramInfo::~ProgramInfo() { | 1091 Program::~Program() { |
1092 if (manager_) { | 1092 if (manager_) { |
1093 if (manager_->have_context_) { | 1093 if (manager_->have_context_) { |
1094 glDeleteProgram(service_id()); | 1094 glDeleteProgram(service_id()); |
1095 } | 1095 } |
1096 manager_->StopTracking(this); | 1096 manager_->StopTracking(this); |
1097 manager_ = NULL; | 1097 manager_ = NULL; |
1098 } | 1098 } |
1099 } | 1099 } |
1100 | 1100 |
1101 | 1101 |
1102 ProgramManager::ProgramManager(ProgramCache* program_cache) | 1102 ProgramManager::ProgramManager(ProgramCache* program_cache) |
1103 : program_info_count_(0), | 1103 : program_info_count_(0), |
1104 have_context_(true), | 1104 have_context_(true), |
1105 disable_workarounds_( | 1105 disable_workarounds_( |
1106 CommandLine::ForCurrentProcess()->HasSwitch( | 1106 CommandLine::ForCurrentProcess()->HasSwitch( |
1107 switches::kDisableGpuDriverBugWorkarounds)), | 1107 switches::kDisableGpuDriverBugWorkarounds)), |
1108 program_cache_(program_cache) { } | 1108 program_cache_(program_cache) { } |
1109 | 1109 |
1110 ProgramManager::~ProgramManager() { | 1110 ProgramManager::~ProgramManager() { |
1111 DCHECK(program_infos_.empty()); | 1111 DCHECK(program_infos_.empty()); |
1112 } | 1112 } |
1113 | 1113 |
1114 void ProgramManager::Destroy(bool have_context) { | 1114 void ProgramManager::Destroy(bool have_context) { |
1115 have_context_ = have_context; | 1115 have_context_ = have_context; |
1116 program_infos_.clear(); | 1116 program_infos_.clear(); |
1117 } | 1117 } |
1118 | 1118 |
1119 void ProgramManager::StartTracking(ProgramManager::ProgramInfo* /* program */) { | 1119 void ProgramManager::StartTracking(Program* /* program */) { |
1120 ++program_info_count_; | 1120 ++program_info_count_; |
1121 } | 1121 } |
1122 | 1122 |
1123 void ProgramManager::StopTracking(ProgramManager::ProgramInfo* /* program */) { | 1123 void ProgramManager::StopTracking(Program* /* program */) { |
1124 --program_info_count_; | 1124 --program_info_count_; |
1125 } | 1125 } |
1126 | 1126 |
1127 ProgramManager::ProgramInfo* ProgramManager::CreateProgramInfo( | 1127 Program* ProgramManager::CreateProgram( |
1128 GLuint client_id, GLuint service_id) { | 1128 GLuint client_id, GLuint service_id) { |
1129 std::pair<ProgramInfoMap::iterator, bool> result = | 1129 std::pair<ProgramInfoMap::iterator, bool> result = |
1130 program_infos_.insert( | 1130 program_infos_.insert( |
1131 std::make_pair(client_id, | 1131 std::make_pair(client_id, |
1132 ProgramInfo::Ref(new ProgramInfo(this, service_id)))); | 1132 scoped_refptr<Program>( |
| 1133 new Program(this, service_id)))); |
1133 DCHECK(result.second); | 1134 DCHECK(result.second); |
1134 return result.first->second; | 1135 return result.first->second; |
1135 } | 1136 } |
1136 | 1137 |
1137 ProgramManager::ProgramInfo* ProgramManager::GetProgramInfo(GLuint client_id) { | 1138 Program* ProgramManager::GetProgram(GLuint client_id) { |
1138 ProgramInfoMap::iterator it = program_infos_.find(client_id); | 1139 ProgramInfoMap::iterator it = program_infos_.find(client_id); |
1139 return it != program_infos_.end() ? it->second : NULL; | 1140 return it != program_infos_.end() ? it->second : NULL; |
1140 } | 1141 } |
1141 | 1142 |
1142 bool ProgramManager::GetClientId(GLuint service_id, GLuint* client_id) const { | 1143 bool ProgramManager::GetClientId(GLuint service_id, GLuint* client_id) const { |
1143 // This doesn't need to be fast. It's only used during slow queries. | 1144 // This doesn't need to be fast. It's only used during slow queries. |
1144 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); | 1145 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); |
1145 it != program_infos_.end(); ++it) { | 1146 it != program_infos_.end(); ++it) { |
1146 if (it->second->service_id() == service_id) { | 1147 if (it->second->service_id() == service_id) { |
1147 *client_id = it->first; | 1148 *client_id = it->first; |
1148 return true; | 1149 return true; |
1149 } | 1150 } |
1150 } | 1151 } |
1151 return false; | 1152 return false; |
1152 } | 1153 } |
1153 | 1154 |
1154 ProgramCache* ProgramManager::program_cache() const { | 1155 ProgramCache* ProgramManager::program_cache() const { |
1155 return program_cache_; | 1156 return program_cache_; |
1156 } | 1157 } |
1157 | 1158 |
1158 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { | 1159 bool ProgramManager::IsOwned(Program* info) { |
1159 for (ProgramInfoMap::iterator it = program_infos_.begin(); | 1160 for (ProgramInfoMap::iterator it = program_infos_.begin(); |
1160 it != program_infos_.end(); ++it) { | 1161 it != program_infos_.end(); ++it) { |
1161 if (it->second.get() == info) { | 1162 if (it->second.get() == info) { |
1162 return true; | 1163 return true; |
1163 } | 1164 } |
1164 } | 1165 } |
1165 return false; | 1166 return false; |
1166 } | 1167 } |
1167 | 1168 |
1168 void ProgramManager::RemoveProgramInfoIfUnused( | 1169 void ProgramManager::RemoveProgramInfoIfUnused( |
1169 ShaderManager* shader_manager, ProgramInfo* info) { | 1170 ShaderManager* shader_manager, Program* info) { |
1170 DCHECK(shader_manager); | 1171 DCHECK(shader_manager); |
1171 DCHECK(info); | 1172 DCHECK(info); |
1172 DCHECK(IsOwned(info)); | 1173 DCHECK(IsOwned(info)); |
1173 if (info->IsDeleted() && !info->InUse()) { | 1174 if (info->IsDeleted() && !info->InUse()) { |
1174 info->DetachShaders(shader_manager); | 1175 info->DetachShaders(shader_manager); |
1175 for (ProgramInfoMap::iterator it = program_infos_.begin(); | 1176 for (ProgramInfoMap::iterator it = program_infos_.begin(); |
1176 it != program_infos_.end(); ++it) { | 1177 it != program_infos_.end(); ++it) { |
1177 if (it->second.get() == info) { | 1178 if (it->second.get() == info) { |
1178 program_infos_.erase(it); | 1179 program_infos_.erase(it); |
1179 return; | 1180 return; |
1180 } | 1181 } |
1181 } | 1182 } |
1182 NOTREACHED(); | 1183 NOTREACHED(); |
1183 } | 1184 } |
1184 } | 1185 } |
1185 | 1186 |
1186 void ProgramManager::MarkAsDeleted( | 1187 void ProgramManager::MarkAsDeleted( |
1187 ShaderManager* shader_manager, | 1188 ShaderManager* shader_manager, |
1188 ProgramManager::ProgramInfo* info) { | 1189 Program* info) { |
1189 DCHECK(shader_manager); | 1190 DCHECK(shader_manager); |
1190 DCHECK(info); | 1191 DCHECK(info); |
1191 DCHECK(IsOwned(info)); | 1192 DCHECK(IsOwned(info)); |
1192 info->MarkAsDeleted(); | 1193 info->MarkAsDeleted(); |
1193 RemoveProgramInfoIfUnused(shader_manager, info); | 1194 RemoveProgramInfoIfUnused(shader_manager, info); |
1194 } | 1195 } |
1195 | 1196 |
1196 void ProgramManager::UseProgram(ProgramManager::ProgramInfo* info) { | 1197 void ProgramManager::UseProgram(Program* info) { |
1197 DCHECK(info); | 1198 DCHECK(info); |
1198 DCHECK(IsOwned(info)); | 1199 DCHECK(IsOwned(info)); |
1199 info->IncUseCount(); | 1200 info->IncUseCount(); |
1200 ClearUniforms(info); | 1201 ClearUniforms(info); |
1201 } | 1202 } |
1202 | 1203 |
1203 void ProgramManager::UnuseProgram( | 1204 void ProgramManager::UnuseProgram( |
1204 ShaderManager* shader_manager, | 1205 ShaderManager* shader_manager, |
1205 ProgramManager::ProgramInfo* info) { | 1206 Program* info) { |
1206 DCHECK(shader_manager); | 1207 DCHECK(shader_manager); |
1207 DCHECK(info); | 1208 DCHECK(info); |
1208 DCHECK(IsOwned(info)); | 1209 DCHECK(IsOwned(info)); |
1209 info->DecUseCount(); | 1210 info->DecUseCount(); |
1210 RemoveProgramInfoIfUnused(shader_manager, info); | 1211 RemoveProgramInfoIfUnused(shader_manager, info); |
1211 } | 1212 } |
1212 | 1213 |
1213 void ProgramManager::ClearUniforms(ProgramManager::ProgramInfo* info) { | 1214 void ProgramManager::ClearUniforms(Program* info) { |
1214 DCHECK(info); | 1215 DCHECK(info); |
1215 if (!disable_workarounds_) { | 1216 if (!disable_workarounds_) { |
1216 info->ClearUniforms(&zero_); | 1217 info->ClearUniforms(&zero_); |
1217 } | 1218 } |
1218 } | 1219 } |
1219 | 1220 |
1220 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { | 1221 int32 ProgramManager::MakeFakeLocation(int32 index, int32 element) { |
1221 return index + element * 0x10000; | 1222 return index + element * 0x10000; |
1222 } | 1223 } |
1223 | 1224 |
1224 } // namespace gles2 | 1225 } // namespace gles2 |
1225 } // namespace gpu | 1226 } // namespace gpu |
OLD | NEW |