Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: gpu/command_buffer/client/program_info_manager.cc

Issue 7358006: Cache OpenGL program info on the client side of the command buffer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix warnings Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 "../client/program_info_manager.h"
6 #include "../client/gles2_implementation.h"
7
8 #include <map>
9
10 namespace gpu {
11 namespace gles2 {
12
13 class NonCachedProgramInfoManager : public ProgramInfoManager {
14 public:
15 NonCachedProgramInfoManager();
16 virtual ~NonCachedProgramInfoManager();
17
18 virtual void CreateInfo(GLuint program);
19
20 virtual void DeleteInfo(GLuint program);
21
22 virtual bool GetProgramiv(
23 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params);
24
25 virtual GLint GetAttribLocation(
26 GLES2Implementation* gl, GLuint program, const char* name);
27
28 virtual GLint GetUniformLocation(
29 GLES2Implementation* gl, GLuint program, const char* name);
30
31 virtual bool GetActiveAttrib(
32 GLES2Implementation* gl,
33 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
34 GLint* size, GLenum* type, char* name);
35
36 virtual bool GetActiveUniform(
37 GLES2Implementation* gl,
38 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
39 GLint* size, GLenum* type, char* name);
40
41 };
42
43 NonCachedProgramInfoManager::NonCachedProgramInfoManager() {
44 }
45
46 NonCachedProgramInfoManager::~NonCachedProgramInfoManager() {
47 }
48
49 void NonCachedProgramInfoManager::CreateInfo(GLuint /* program */) {
50 }
51
52 void NonCachedProgramInfoManager::DeleteInfo(GLuint /* program */) {
53 }
54
55 bool NonCachedProgramInfoManager::GetProgramiv(
56 GLES2Implementation* /* gl */,
57 GLuint /* program */,
58 GLenum /* pname */,
59 GLint* /* params */) {
60 return false;
61 }
62
63 GLint NonCachedProgramInfoManager::GetAttribLocation(
64 GLES2Implementation* gl, GLuint program, const char* name) {
65 return gl->GetAttribLocationHelper(program, name);
66 }
67
68 GLint NonCachedProgramInfoManager::GetUniformLocation(
69 GLES2Implementation* gl, GLuint program, const char* name) {
70 return gl->GetUniformLocationHelper(program, name);
71 }
72
73 bool NonCachedProgramInfoManager::GetActiveAttrib(
74 GLES2Implementation* gl,
75 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
76 GLint* size, GLenum* type, char* name) {
77 return gl->GetActiveAttribHelper(
78 program, index, bufsize, length, size, type, name);
79 }
80
81 bool NonCachedProgramInfoManager::GetActiveUniform(
82 GLES2Implementation* gl,
83 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
84 GLint* size, GLenum* type, char* name) {
85 return gl->GetActiveUniformHelper(
86 program, index, bufsize, length, size, type, name);
87 }
88
89 class CachedProgramInfoManager : public ProgramInfoManager {
90 public:
91 CachedProgramInfoManager();
92 virtual ~CachedProgramInfoManager();
93
94 virtual void CreateInfo(GLuint program);
95
96 virtual void DeleteInfo(GLuint program);
97
98 virtual bool GetProgramiv(
99 GLES2Implementation* gl,
100 GLuint program, GLenum pname, GLint* params);
101
102 virtual GLint GetAttribLocation(
103 GLES2Implementation* gl, GLuint program, const char* name);
104
105 virtual GLint GetUniformLocation(
106 GLES2Implementation* gl, GLuint program, const char* name);
107
108 virtual bool GetActiveAttrib(
109 GLES2Implementation* gl,
110 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
111 GLint* size, GLenum* type, char* name);
112
113 virtual bool GetActiveUniform(
114 GLES2Implementation* gl,
115 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
116 GLint* size, GLenum* type, char* name);
117
118 private:
119 class ProgramInfo {
120 public:
121 struct UniformInfo {
122 UniformInfo(GLsizei _size, GLenum _type, const std::string& _name);
123
124 GLsizei size;
125 GLenum type;
126 bool is_array;
127 std::string name;
128 std::vector<GLint> element_locations;
129 };
130 struct VertexAttribInfo {
131 VertexAttribInfo(GLsizei _size, GLenum _type, const std::string& _name,
132 GLint _location)
133 : size(_size),
134 type(_type),
135 location(_location),
136 name(_name) {
137 }
138 GLsizei size;
139 GLenum type;
140 GLint location;
141 std::string name;
142 };
143
144 typedef std::vector<UniformInfo> UniformInfoVector;
145 typedef std::vector<VertexAttribInfo> AttribInfoVector;
146
147 ProgramInfo();
148
149 const AttribInfoVector& GetAttribInfos() const {
150 return attrib_infos_;
151 }
152
153 const VertexAttribInfo* GetAttribInfo(GLint index) const {
154 return (static_cast<size_t>(index) < attrib_infos_.size()) ?
155 &attrib_infos_[index] : NULL;
156 }
157
158 GLint GetAttribLocation(const std::string& name) const;
159
160 const UniformInfo* GetUniformInfo(GLint index) const {
161 return (static_cast<size_t>(index) < uniform_infos_.size()) ?
162 &uniform_infos_[index] : NULL;
163 }
164
165 // Gets the location of a uniform by name.
166 GLint GetUniformLocation(const std::string& name) const;
167
168 bool GetProgramiv(GLenum pname, GLint* params);
169
170 // Updates the program info after a successful link.
171 void Update(GLES2Implementation* gl, GLuint program);
172
173 private:
174 GLsizei max_attrib_name_length_;
175
176 // Attrib by index.
177 AttribInfoVector attrib_infos_;
178
179 GLsizei max_uniform_name_length_;
180
181 // Uniform info by index.
182 UniformInfoVector uniform_infos_;
183
184 // This is true if glLinkProgram was successful last time it was called.
185 bool link_status_;
186 };
187
188 ProgramInfo* GetProgramInfo(GLES2Implementation* gl, GLuint program);
189
190 // TODO(gman): Switch to a faster container.
191 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap;
192
193 ProgramInfoMap program_infos_;
194 };
195
196 CachedProgramInfoManager::ProgramInfo::UniformInfo::UniformInfo(
197 GLsizei _size, GLenum _type, const std::string& _name)
198 : size(_size),
199 type(_type),
200 name(_name) {
201 is_array = (!name.empty() && name[name.size() - 1] == ']');
202 GPU_DCHECK((size < 2 || !is_array));
203 }
204
205 CachedProgramInfoManager::ProgramInfo::ProgramInfo()
206 : max_attrib_name_length_(0),
207 max_uniform_name_length_(0),
208 link_status_(false) {
209 }
210
211 // TODO(gman): Add a faster lookup.
212 GLint CachedProgramInfoManager::ProgramInfo::GetAttribLocation(
213 const std::string& name) const {
214 for (GLuint ii = 0; ii < attrib_infos_.size(); ++ii) {
215 const VertexAttribInfo& info = attrib_infos_[ii];
216 if (info.name == name) {
217 return info.location;
218 }
219 }
220 return -1;
221 }
222
223 // TODO(gman): Add a faster lookup.
224 GLint CachedProgramInfoManager::ProgramInfo::GetUniformLocation(
225 const std::string& name) const {
226 for (GLuint ii = 0; ii < uniform_infos_.size(); ++ii) {
227 const UniformInfo& info = uniform_infos_[ii];
228 if (info.name == name ||
229 (info.is_array &&
230 info.name.compare(0, info.name.size() - 3, name) == 0)) {
231 return info.element_locations[0];
232 } else if (info.is_array &&
233 name.size() >= 3 && name[name.size() - 1] == ']') {
234 // Look for an array specification.
235 size_t open_pos = name.find_last_of('[');
236 if (open_pos != std::string::npos &&
237 open_pos < name.size() - 2 &&
238 info.name.size() > open_pos &&
239 name.compare(0, open_pos, info.name, 0, open_pos) == 0) {
240 GLint index = 0;
241 size_t last = name.size() - 1;
242 bool bad = false;
243 for (size_t pos = open_pos + 1; pos < last; ++pos) {
244 int8 digit = name[pos] - '0';
245 if (digit < 0 || digit > 9) {
246 bad = true;
247 break;
248 }
249 index = index * 10 + digit;
250 }
251 if (!bad && index >= 0 && index < info.size) {
252 return info.element_locations[index];
253 }
254 }
255 }
256 }
257 return -1;
258 }
259
260 bool CachedProgramInfoManager::ProgramInfo::GetProgramiv(
261 GLenum pname, GLint* params) {
262 switch (pname) {
263 case GL_LINK_STATUS:
264 *params = link_status_;
265 return true;
266 case GL_ACTIVE_ATTRIBUTES:
267 *params = attrib_infos_.size();
268 return true;
269 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
270 *params = max_attrib_name_length_;
271 return true;
272 case GL_ACTIVE_UNIFORMS:
273 *params = uniform_infos_.size();
274 return true;
275 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
276 *params = max_uniform_name_length_;
277 return true;
278 default:
279 break;
280 }
281 return false;
282 }
283
284 template<typename T> static T LocalGetAs(
285 const std::vector<int8>& data, uint32 offset, size_t size) {
286 const int8* p = &data[0] + offset;
287 if (offset + size > data.size()) {
288 GPU_NOTREACHED();
289 return NULL;
290 }
291 return static_cast<T>(static_cast<const void*>(p));
292 }
293
294 void CachedProgramInfoManager::ProgramInfo::Update(
295 GLES2Implementation* gl, GLuint program) {
296 std::vector<int8> result;
297 gl->GetProgramInfoCHROMIUMHelper(program, &result);
298 if (result.empty()) {
299 // This should only happen on a lost context.
300 return;
301 }
302 GPU_DCHECK_GE(result.size(), sizeof(ProgramInfoHeader));
303 const ProgramInfoHeader* header = LocalGetAs<const ProgramInfoHeader*>(
304 result, 0, sizeof(header));
305 link_status_ = header->link_status != 0;
306 if (!link_status_) {
307 return;
308 }
309 attrib_infos_.clear();
310 uniform_infos_.clear();
311 max_attrib_name_length_ = 0;
312 max_uniform_name_length_ = 0;
313 const ProgramInput* inputs = LocalGetAs<const ProgramInput*>(
314 result, sizeof(*header),
315 sizeof(ProgramInput) * (header->num_attribs + header->num_attribs));
316 const ProgramInput* input = inputs;
317 for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
318 const int32* location = LocalGetAs<const int32*>(
319 result, input->location_offset, sizeof(int32));
320 const char* name_buf = LocalGetAs<const char*>(
321 result, input->name_offset, input->name_length);
322 std::string name(name_buf, input->name_length);
323 attrib_infos_.push_back(
324 VertexAttribInfo(input->size, input->type, name, *location));
325 max_attrib_name_length_ = std::max(
326 static_cast<GLsizei>(name.size()), max_attrib_name_length_);
327 ++input;
328 }
329 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
330 const int32* locations = LocalGetAs<const int32*>(
331 result, input->location_offset, sizeof(int32) * input->size);
332 const char* name_buf = LocalGetAs<const char*>(
333 result, input->name_offset, input->name_length);
334 std::string name(name_buf, input->name_length);
335 UniformInfo info(input->size, input->type, name);
336 max_uniform_name_length_ = std::max(
337 static_cast<GLsizei>(name.size()), max_uniform_name_length_);
338 for (int32 jj = 0; jj < input->size; ++jj) {
339 info.element_locations.push_back(locations[jj]);
340 }
341 uniform_infos_.push_back(info);
342 ++input;
343 }
344 GPU_DCHECK_EQ(header->num_attribs + header->num_uniforms,
345 static_cast<uint32>(input - inputs));
346 }
347
348 CachedProgramInfoManager::CachedProgramInfoManager() {
349 }
350
351 CachedProgramInfoManager::~CachedProgramInfoManager() {
352
353 }
354
355 CachedProgramInfoManager::ProgramInfo*
356 CachedProgramInfoManager::GetProgramInfo(
357 GLES2Implementation* gl, GLuint program) {
358 ProgramInfoMap::iterator it = program_infos_.find(program);
359 if (it == program_infos_.end()) {
360 return NULL;
361 }
362 ProgramInfo* info = &it->second;
363 info->Update(gl, program);
364 return info;
365 }
366
367 void CachedProgramInfoManager::CreateInfo(GLuint program) {
368 DeleteInfo(program);
369 std::pair<ProgramInfoMap::iterator, bool> result =
370 program_infos_.insert(std::make_pair(program, ProgramInfo()));
371
372 GPU_DCHECK(result.second);
373 }
374
375 void CachedProgramInfoManager::DeleteInfo(GLuint program) {
376 program_infos_.erase(program);
377 }
378
379 bool CachedProgramInfoManager::GetProgramiv(
380 GLES2Implementation* gl, GLuint program, GLenum pname, GLint* params) {
381 ProgramInfo* info = GetProgramInfo(gl, program);
382 if (!info) {
383 return false;
384 }
385 return info->GetProgramiv(pname, params);
386 }
387
388 GLint CachedProgramInfoManager::GetAttribLocation(
389 GLES2Implementation* gl, GLuint program, const char* name) {
390 ProgramInfo* info = GetProgramInfo(gl, program);
391 if (!info) {
392 return -1;
393 }
394 return info->GetAttribLocation(name);
395 }
396
397 GLint CachedProgramInfoManager::GetUniformLocation(
398 GLES2Implementation* gl, GLuint program, const char* name) {
399 ProgramInfo* info = GetProgramInfo(gl, program);
400 if (!info) {
401 return -1;
402 }
403 return info->GetUniformLocation(name);
404 }
405
406 bool CachedProgramInfoManager::GetActiveAttrib(
407 GLES2Implementation* gl,
408 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
409 GLint* size, GLenum* type, char* name) {
410 ProgramInfo* info = GetProgramInfo(gl, program);
411 if (!info) {
412 return false;
413 }
414 const ProgramInfo::VertexAttribInfo* attrib_info = info->GetAttribInfo(index);
415 if (!attrib_info) {
416 return false;
417 }
418 if (size) {
419 *size = attrib_info->size;
420 }
421 if (type) {
422 *type = attrib_info->type;
423 }
424 if (length || name) {
425 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1,
426 std::max(static_cast<size_t>(0),
427 attrib_info->name.size() - 1));
428 if (length) {
429 *length = max_size;
430 }
431 if (name && bufsize > 0) {
432 memcpy(name, attrib_info->name.c_str(), max_size);
433 name[max_size] = '\0';
434 }
435 }
436 return true;
437 }
438
439 bool CachedProgramInfoManager::GetActiveUniform(
440 GLES2Implementation* gl,
441 GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
442 GLint* size, GLenum* type, char* name) {
443 ProgramInfo* info = GetProgramInfo(gl, program);
444 if (!info) {
445 return false;
446 }
447 const ProgramInfo::UniformInfo* uniform_info = info->GetUniformInfo(index);
448 if (!uniform_info) {
449 return false;
450 }
451 if (size) {
452 *size = uniform_info->size;
453 }
454 if (type) {
455 *type = uniform_info->type;
456 }
457 if (length || name) {
458 GLsizei max_size = std::min(static_cast<size_t>(bufsize) - 1,
459 std::max(static_cast<size_t>(0),
460 uniform_info->name.size() - 1));
461 if (length) {
462 *length = max_size;
463 }
464 if (name && bufsize > 0) {
465 memcpy(name, uniform_info->name.c_str(), max_size);
466 name[max_size] = '\0';
467 }
468 }
469 return true;
470 }
471
472 ProgramInfoManager::ProgramInfoManager() {
473 }
474
475 ProgramInfoManager::~ProgramInfoManager() {
476 }
477
478 ProgramInfoManager* ProgramInfoManager::Create(bool shared_resources) {
479 if (shared_resources) {
480 return new NonCachedProgramInfoManager();
481 } else {
482 return new CachedProgramInfoManager();
483 }
484 }
485
486 } // namespace gles2
487 } // namespace gpu
488
489
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698