| 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/client/program_info_manager.h" | 5 #include "gpu/command_buffer/client/program_info_manager.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
| 10 #include "base/containers/hash_tables.h" |
| 10 #include "base/synchronization/lock.h" | 11 #include "base/synchronization/lock.h" |
| 11 #include "gpu/command_buffer/client/gles2_implementation.h" | 12 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 12 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 13 | 14 |
| 14 namespace gpu { | 15 namespace gpu { |
| 15 namespace gles2 { | 16 namespace gles2 { |
| 16 | 17 |
| 17 class NonCachedProgramInfoManager : public ProgramInfoManager { | 18 class NonCachedProgramInfoManager : public ProgramInfoManager { |
| 18 public: | 19 public: |
| 19 NonCachedProgramInfoManager(); | 20 NonCachedProgramInfoManager(); |
| 20 ~NonCachedProgramInfoManager() override; | 21 ~NonCachedProgramInfoManager() override; |
| 21 | 22 |
| 22 void CreateInfo(GLuint program) override; | 23 void CreateInfo(GLuint program) override; |
| 23 | 24 |
| 24 void DeleteInfo(GLuint program) override; | 25 void DeleteInfo(GLuint program) override; |
| 25 | 26 |
| 26 bool GetProgramiv(GLES2Implementation* gl, | 27 bool GetProgramiv(GLES2Implementation* gl, |
| 27 GLuint program, | 28 GLuint program, |
| 28 GLenum pname, | 29 GLenum pname, |
| 29 GLint* params) override; | 30 GLint* params) override; |
| 30 | 31 |
| 31 GLint GetAttribLocation(GLES2Implementation* gl, | 32 GLint GetAttribLocation(GLES2Implementation* gl, |
| 32 GLuint program, | 33 GLuint program, |
| 33 const char* name) override; | 34 const char* name) override; |
| 34 | 35 |
| 35 GLint GetUniformLocation(GLES2Implementation* gl, | 36 GLint GetUniformLocation(GLES2Implementation* gl, |
| 36 GLuint program, | 37 GLuint program, |
| 37 const char* name) override; | 38 const char* name) override; |
| 38 | 39 |
| 40 GLint GetFragDataLocation(GLES2Implementation* gl, |
| 41 GLuint program, |
| 42 const char* name) override; |
| 43 |
| 39 bool GetActiveAttrib(GLES2Implementation* gl, | 44 bool GetActiveAttrib(GLES2Implementation* gl, |
| 40 GLuint program, | 45 GLuint program, |
| 41 GLuint index, | 46 GLuint index, |
| 42 GLsizei bufsize, | 47 GLsizei bufsize, |
| 43 GLsizei* length, | 48 GLsizei* length, |
| 44 GLint* size, | 49 GLint* size, |
| 45 GLenum* type, | 50 GLenum* type, |
| 46 char* name) override; | 51 char* name) override; |
| 47 | 52 |
| 48 bool GetActiveUniform(GLES2Implementation* gl, | 53 bool GetActiveUniform(GLES2Implementation* gl, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 78 GLint NonCachedProgramInfoManager::GetAttribLocation( | 83 GLint NonCachedProgramInfoManager::GetAttribLocation( |
| 79 GLES2Implementation* gl, GLuint program, const char* name) { | 84 GLES2Implementation* gl, GLuint program, const char* name) { |
| 80 return gl->GetAttribLocationHelper(program, name); | 85 return gl->GetAttribLocationHelper(program, name); |
| 81 } | 86 } |
| 82 | 87 |
| 83 GLint NonCachedProgramInfoManager::GetUniformLocation( | 88 GLint NonCachedProgramInfoManager::GetUniformLocation( |
| 84 GLES2Implementation* gl, GLuint program, const char* name) { | 89 GLES2Implementation* gl, GLuint program, const char* name) { |
| 85 return gl->GetUniformLocationHelper(program, name); | 90 return gl->GetUniformLocationHelper(program, name); |
| 86 } | 91 } |
| 87 | 92 |
| 93 GLint NonCachedProgramInfoManager::GetFragDataLocation( |
| 94 GLES2Implementation* gl, GLuint program, const char* name) { |
| 95 return gl->GetFragDataLocationHelper(program, name); |
| 96 } |
| 97 |
| 88 bool NonCachedProgramInfoManager::GetActiveAttrib( | 98 bool NonCachedProgramInfoManager::GetActiveAttrib( |
| 89 GLES2Implementation* gl, | 99 GLES2Implementation* gl, |
| 90 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 100 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
| 91 GLint* size, GLenum* type, char* name) { | 101 GLint* size, GLenum* type, char* name) { |
| 92 return gl->GetActiveAttribHelper( | 102 return gl->GetActiveAttribHelper( |
| 93 program, index, bufsize, length, size, type, name); | 103 program, index, bufsize, length, size, type, name); |
| 94 } | 104 } |
| 95 | 105 |
| 96 bool NonCachedProgramInfoManager::GetActiveUniform( | 106 bool NonCachedProgramInfoManager::GetActiveUniform( |
| 97 GLES2Implementation* gl, | 107 GLES2Implementation* gl, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 116 GLint* params) override; | 126 GLint* params) override; |
| 117 | 127 |
| 118 GLint GetAttribLocation(GLES2Implementation* gl, | 128 GLint GetAttribLocation(GLES2Implementation* gl, |
| 119 GLuint program, | 129 GLuint program, |
| 120 const char* name) override; | 130 const char* name) override; |
| 121 | 131 |
| 122 GLint GetUniformLocation(GLES2Implementation* gl, | 132 GLint GetUniformLocation(GLES2Implementation* gl, |
| 123 GLuint program, | 133 GLuint program, |
| 124 const char* name) override; | 134 const char* name) override; |
| 125 | 135 |
| 136 GLint GetFragDataLocation(GLES2Implementation* gl, |
| 137 GLuint program, |
| 138 const char* name) override; |
| 139 |
| 126 bool GetActiveAttrib(GLES2Implementation* gl, | 140 bool GetActiveAttrib(GLES2Implementation* gl, |
| 127 GLuint program, | 141 GLuint program, |
| 128 GLuint index, | 142 GLuint index, |
| 129 GLsizei bufsize, | 143 GLsizei bufsize, |
| 130 GLsizei* length, | 144 GLsizei* length, |
| 131 GLint* size, | 145 GLint* size, |
| 132 GLenum* type, | 146 GLenum* type, |
| 133 char* name) override; | 147 char* name) override; |
| 134 | 148 |
| 135 bool GetActiveUniform(GLES2Implementation* gl, | 149 bool GetActiveUniform(GLES2Implementation* gl, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 GLint GetAttribLocation(const std::string& name) const; | 198 GLint GetAttribLocation(const std::string& name) const; |
| 185 | 199 |
| 186 const UniformInfo* GetUniformInfo(GLint index) const { | 200 const UniformInfo* GetUniformInfo(GLint index) const { |
| 187 return (static_cast<size_t>(index) < uniform_infos_.size()) ? | 201 return (static_cast<size_t>(index) < uniform_infos_.size()) ? |
| 188 &uniform_infos_[index] : NULL; | 202 &uniform_infos_[index] : NULL; |
| 189 } | 203 } |
| 190 | 204 |
| 191 // Gets the location of a uniform by name. | 205 // Gets the location of a uniform by name. |
| 192 GLint GetUniformLocation(const std::string& name) const; | 206 GLint GetUniformLocation(const std::string& name) const; |
| 193 | 207 |
| 208 GLint GetFragDataLocation(const std::string& name) const; |
| 209 void CacheFragDataLocation(const std::string& name, GLint loc); |
| 210 |
| 194 bool GetProgramiv(GLenum pname, GLint* params); | 211 bool GetProgramiv(GLenum pname, GLint* params); |
| 195 | 212 |
| 196 // Updates the program info after a successful link. | 213 // Updates the program info after a successful link. |
| 197 void Update(GLES2Implementation* gl, | 214 void Update(GLES2Implementation* gl, |
| 198 GLuint program, | 215 GLuint program, |
| 199 const std::vector<int8>& result); | 216 const std::vector<int8>& result); |
| 200 | 217 |
| 201 bool cached() const { return cached_; } | 218 bool cached() const { return cached_; } |
| 202 | 219 |
| 203 private: | 220 private: |
| 204 bool cached_; | 221 bool cached_; |
| 205 | 222 |
| 206 GLsizei max_attrib_name_length_; | 223 GLsizei max_attrib_name_length_; |
| 207 | 224 |
| 208 // Attrib by index. | 225 // Attrib by index. |
| 209 AttribInfoVector attrib_infos_; | 226 AttribInfoVector attrib_infos_; |
| 210 | 227 |
| 211 GLsizei max_uniform_name_length_; | 228 GLsizei max_uniform_name_length_; |
| 212 | 229 |
| 213 // Uniform info by index. | 230 // Uniform info by index. |
| 214 UniformInfoVector uniform_infos_; | 231 UniformInfoVector uniform_infos_; |
| 215 | 232 |
| 233 base::hash_map<std::string, GLint> frag_data_locations_; |
| 234 |
| 216 // This is true if glLinkProgram was successful last time it was called. | 235 // This is true if glLinkProgram was successful last time it was called. |
| 217 bool link_status_; | 236 bool link_status_; |
| 218 }; | 237 }; |
| 219 | 238 |
| 220 Program* GetProgramInfo(GLES2Implementation* gl, GLuint program); | 239 Program* GetProgramInfo(GLES2Implementation* gl, GLuint program); |
| 221 | 240 |
| 222 // TODO(gman): Switch to a faster container. | 241 typedef base::hash_map<GLuint, Program> ProgramInfoMap; |
| 223 typedef std::map<GLuint, Program> ProgramInfoMap; | |
| 224 | 242 |
| 225 ProgramInfoMap program_infos_; | 243 ProgramInfoMap program_infos_; |
| 226 | 244 |
| 227 mutable base::Lock lock_; | 245 mutable base::Lock lock_; |
| 228 }; | 246 }; |
| 229 | 247 |
| 230 CachedProgramInfoManager::Program::UniformInfo::UniformInfo( | 248 CachedProgramInfoManager::Program::UniformInfo::UniformInfo( |
| 231 GLsizei _size, GLenum _type, const std::string& _name) | 249 GLsizei _size, GLenum _type, const std::string& _name) |
| 232 : size(_size), | 250 : size(_size), |
| 233 type(_type), | 251 type(_type), |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 name.compare(0, open_pos, info.name, 0, open_pos) == 0) { | 295 name.compare(0, open_pos, info.name, 0, open_pos) == 0) { |
| 278 if (index >= 0 && index < info.size) { | 296 if (index >= 0 && index < info.size) { |
| 279 return info.element_locations[index]; | 297 return info.element_locations[index]; |
| 280 } | 298 } |
| 281 } | 299 } |
| 282 } | 300 } |
| 283 } | 301 } |
| 284 return -1; | 302 return -1; |
| 285 } | 303 } |
| 286 | 304 |
| 305 GLint CachedProgramInfoManager::Program::GetFragDataLocation( |
| 306 const std::string& name) const { |
| 307 base::hash_map<std::string, GLint>::const_iterator iter = |
| 308 frag_data_locations_.find(name); |
| 309 if (iter == frag_data_locations_.end()) |
| 310 return -1; |
| 311 return iter->second; |
| 312 } |
| 313 |
| 314 void CachedProgramInfoManager::Program::CacheFragDataLocation( |
| 315 const std::string& name, GLint loc) { |
| 316 frag_data_locations_[name] = loc; |
| 317 } |
| 318 |
| 287 bool CachedProgramInfoManager::Program::GetProgramiv( | 319 bool CachedProgramInfoManager::Program::GetProgramiv( |
| 288 GLenum pname, GLint* params) { | 320 GLenum pname, GLint* params) { |
| 289 switch (pname) { | 321 switch (pname) { |
| 290 case GL_LINK_STATUS: | 322 case GL_LINK_STATUS: |
| 291 *params = link_status_; | 323 *params = link_status_; |
| 292 return true; | 324 return true; |
| 293 case GL_ACTIVE_ATTRIBUTES: | 325 case GL_ACTIVE_ATTRIBUTES: |
| 294 *params = attrib_infos_.size(); | 326 *params = attrib_infos_.size(); |
| 295 return true; | 327 return true; |
| 296 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: | 328 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 363 } |
| 332 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); | 364 DCHECK_GE(result.size(), sizeof(ProgramInfoHeader)); |
| 333 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( | 365 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>( |
| 334 result, 0, sizeof(header)); | 366 result, 0, sizeof(header)); |
| 335 link_status_ = header->link_status != 0; | 367 link_status_ = header->link_status != 0; |
| 336 if (!link_status_) { | 368 if (!link_status_) { |
| 337 return; | 369 return; |
| 338 } | 370 } |
| 339 attrib_infos_.clear(); | 371 attrib_infos_.clear(); |
| 340 uniform_infos_.clear(); | 372 uniform_infos_.clear(); |
| 373 frag_data_locations_.clear(); |
| 341 max_attrib_name_length_ = 0; | 374 max_attrib_name_length_ = 0; |
| 342 max_uniform_name_length_ = 0; | 375 max_uniform_name_length_ = 0; |
| 343 const ProgramInput* inputs = LocalGetAs<const ProgramInput*>( | 376 const ProgramInput* inputs = LocalGetAs<const ProgramInput*>( |
| 344 result, sizeof(*header), | 377 result, sizeof(*header), |
| 345 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms)); | 378 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms)); |
| 346 const ProgramInput* input = inputs; | 379 const ProgramInput* input = inputs; |
| 347 for (uint32 ii = 0; ii < header->num_attribs; ++ii) { | 380 for (uint32 ii = 0; ii < header->num_attribs; ++ii) { |
| 348 const int32* location = LocalGetAs<const int32*>( | 381 const int32* location = LocalGetAs<const int32*>( |
| 349 result, input->location_offset, sizeof(int32)); | 382 result, input->location_offset, sizeof(int32)); |
| 350 const char* name_buf = LocalGetAs<const char*>( | 383 const char* name_buf = LocalGetAs<const char*>( |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 { | 485 { |
| 453 base::AutoLock auto_lock(lock_); | 486 base::AutoLock auto_lock(lock_); |
| 454 Program* info = GetProgramInfo(gl, program); | 487 Program* info = GetProgramInfo(gl, program); |
| 455 if (info) { | 488 if (info) { |
| 456 return info->GetUniformLocation(name); | 489 return info->GetUniformLocation(name); |
| 457 } | 490 } |
| 458 } | 491 } |
| 459 return gl->GetUniformLocationHelper(program, name); | 492 return gl->GetUniformLocationHelper(program, name); |
| 460 } | 493 } |
| 461 | 494 |
| 495 GLint CachedProgramInfoManager::GetFragDataLocation( |
| 496 GLES2Implementation* gl, GLuint program, const char* name) { |
| 497 // TODO(zmo): make FragData locations part of the ProgramInfo that are |
| 498 // fetched altogether from the service side. See crbug.com/452104. |
| 499 { |
| 500 base::AutoLock auto_lock(lock_); |
| 501 Program* info = GetProgramInfo(gl, program); |
| 502 if (info) { |
| 503 GLint possible_loc = info->GetFragDataLocation(name); |
| 504 if (possible_loc != -1) |
| 505 return possible_loc; |
| 506 } |
| 507 } |
| 508 GLint loc = gl->GetFragDataLocationHelper(program, name); |
| 509 if (loc != -1) { |
| 510 base::AutoLock auto_lock(lock_); |
| 511 Program* info = GetProgramInfo(gl, program); |
| 512 if (info) { |
| 513 info->CacheFragDataLocation(name, loc); |
| 514 } |
| 515 } |
| 516 return loc; |
| 517 } |
| 518 |
| 462 bool CachedProgramInfoManager::GetActiveAttrib( | 519 bool CachedProgramInfoManager::GetActiveAttrib( |
| 463 GLES2Implementation* gl, | 520 GLES2Implementation* gl, |
| 464 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, | 521 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, |
| 465 GLint* size, GLenum* type, char* name) { | 522 GLint* size, GLenum* type, char* name) { |
| 466 { | 523 { |
| 467 base::AutoLock auto_lock(lock_); | 524 base::AutoLock auto_lock(lock_); |
| 468 Program* info = GetProgramInfo(gl, program); | 525 Program* info = GetProgramInfo(gl, program); |
| 469 if (info) { | 526 if (info) { |
| 470 const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); | 527 const Program::VertexAttrib* attrib_info = info->GetAttribInfo(index); |
| 471 if (attrib_info) { | 528 if (attrib_info) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 if (shared_resources_across_processes) { | 599 if (shared_resources_across_processes) { |
| 543 return new NonCachedProgramInfoManager(); | 600 return new NonCachedProgramInfoManager(); |
| 544 } else { | 601 } else { |
| 545 return new CachedProgramInfoManager(); | 602 return new CachedProgramInfoManager(); |
| 546 } | 603 } |
| 547 } | 604 } |
| 548 | 605 |
| 549 } // namespace gles2 | 606 } // namespace gles2 |
| 550 } // namespace gpu | 607 } // namespace gpu |
| 551 | 608 |
| OLD | NEW |