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 |