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

Side by Side Diff: gpu/command_buffer/service/program_manager.cc

Issue 10534173: GPU Program Caching (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 6 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
OLDNEW
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 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
11 #include "base/bind.h"
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
14 #include "base/string_number_conversions.h" 15 #include "base/string_number_conversions.h"
16 #include "net/base/net_log.h"
15 #include "gpu/command_buffer/common/gles2_cmd_format.h" 17 #include "gpu/command_buffer/common/gles2_cmd_format.h"
16 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 18 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 19 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
18 #include "gpu/command_buffer/service/gpu_switches.h" 20 #include "gpu/command_buffer/service/gpu_switches.h"
19 21
20 namespace gpu { 22 namespace gpu {
21 namespace gles2 { 23 namespace gles2 {
22 24
23 static int ShaderTypeToIndex(GLenum shader_type) { 25 static int ShaderTypeToIndex(GLenum shader_type) {
24 switch (shader_type) { 26 switch (shader_type) {
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { 248 void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() {
247 for (std::map<std::string, GLint>::const_iterator it = 249 for (std::map<std::string, GLint>::const_iterator it =
248 bind_attrib_location_map_.begin(); 250 bind_attrib_location_map_.begin();
249 it != bind_attrib_location_map_.end(); ++it) { 251 it != bind_attrib_location_map_.end(); ++it) {
250 const std::string* mapped_name = GetAttribMappedName(it->first); 252 const std::string* mapped_name = GetAttribMappedName(it->first);
251 if (mapped_name && *mapped_name != it->first) 253 if (mapped_name && *mapped_name != it->first)
252 glBindAttribLocation(service_id_, it->second, mapped_name->c_str()); 254 glBindAttribLocation(service_id_, it->second, mapped_name->c_str());
253 } 255 }
254 } 256 }
255 257
256 bool ProgramManager::ProgramInfo::Link() { 258 void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info,
259 ShaderTranslator* translator,
260 FeatureInfo::Ref feature_info) {
greggman 2012/06/15 08:10:24 feature_info should just be a raw pointer.
dmurph 2012/06/19 01:08:33 Done.
261 // Translate GL ES 2.0 shader to Desktop GL shader and pass that to
262 // glShaderSource and then glCompileShader.
263 const char* shader_src = info->source() ? info->source()->c_str() : "";
264 if (translator) {
265 if (!translator->Translate(shader_src)) {
266 info->SetStatus(false, translator->info_log(), NULL);
267 if(shader_cache_) {
268 shader_cache_->setShaderCompilationStatus(
269 info->source()->c_str(),
270 SHADER_CACHE_COMPILATION_SUCCEEDED);
271 }
272 return;
273 }
274 shader_src = translator->translated_shader();
275 if (!feature_info->feature_flags().angle_translated_shader_source)
276 info->UpdateTranslatedSource(shader_src);
277 }
278
279 glShaderSource(info->service_id(), 1, &shader_src, NULL);
280 glCompileShader(info->service_id());
281 if (feature_info->feature_flags().angle_translated_shader_source) {
282 GLint max_len = 0;
283 glGetShaderiv(info->service_id(),
284 GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE,
285 &max_len);
286 scoped_array<char> temp(new char[max_len]);
287 GLint len = 0;
288 glGetTranslatedShaderSourceANGLE(
289 info->service_id(), max_len, &len, temp.get());
290 DCHECK(max_len == 0 || len < max_len);
291 DCHECK(len == 0 || temp[len] == '\0');
292 info->UpdateTranslatedSource(temp.get());
293 }
294
295 GLint status = GL_FALSE;
296 glGetShaderiv(info->service_id(), GL_COMPILE_STATUS, &status);
297 if (status) {
298 info->SetStatus(true, "", translator);
299 if(shader_cache_) {
300 shader_cache_->setShaderCompilationStatus(
301 info->source()->c_str(),
302 SHADER_CACHE_COMPILATION_SUCCEEDED);
303 }
304 } else {
305 // We cannot reach here if we are using the shader translator.
306 // All invalid shaders must be rejected by the translator.
307 // All translated shaders must compile.
308 LOG_IF(ERROR, translator)
309 << "Shader translator allowed/produced an invalid shader.";
310 GLint max_len = 0;
311 glGetShaderiv(info->service_id(), GL_INFO_LOG_LENGTH, &max_len);
312 scoped_array<char> temp(new char[max_len]);
313 GLint len = 0;
314 glGetShaderInfoLog(info->service_id(), max_len, &len, temp.get());
315 DCHECK(max_len == 0 || len < max_len);
316 DCHECK(len == 0 || temp[len] == '\0');
317 info->SetStatus(false, std::string(temp.get(), len).c_str(), NULL);
318 if(shader_cache_) {
319 shader_cache_->setShaderCompilationStatus(
320 info->source()->c_str(),
321 SHADER_CACHE_COMPILATION_UNKNOWN);
322 }
323 }
324 }
325
326 bool ProgramManager::ProgramInfo::Link(ShaderManager* manager,
327 ShaderTranslator* vertex_translator,
328 ShaderTranslator* fragment_shader,
329 FeatureInfo::Ref feature_info) {
257 ClearLinkStatus(); 330 ClearLinkStatus();
258 if (!CanLink()) { 331 if (!CanLink()) {
259 set_log_info("missing shaders"); 332 set_log_info("missing shaders");
260 return false; 333 return false;
261 } 334 }
262 if (DetectAttribLocationBindingConflicts()) { 335 if (DetectAttribLocationBindingConflicts()) {
263 set_log_info("glBindAttribLocation() conflicts"); 336 set_log_info("glBindAttribLocation() conflicts");
264 return false; 337 return false;
265 } 338 }
266 ExecuteBindAttribLocationCalls(); 339 ExecuteBindAttribLocationCalls();
267 glLinkProgram(service_id()); 340
341 bool link = true;
342 ShaderCache* cache = manager_->shader_cache_;
343 const char* shader_a = attached_shaders_[0]->source()->c_str();
344 const char* shader_b = attached_shaders_[1]->source()->c_str();
345 if(cache) {
346 LinkedProgramStatus status = cache->getLinkedProgramStatus(
347 shader_a,
348 shader_b);
349 switch(status) {
350 case SHADER_CACHE_LINK_UNKNOWN:
351 fprintf(stderr,
352 "program %i not linked yet compiling and linking\n",
353 service_id());
354 // compile our shaders + attach
355 manager_->DoCompileShader(attached_shaders_[0],
356 vertex_translator,
357 feature_info);
358 manager_->DoCompileShader(attached_shaders_[1],
359 fragment_shader,
360 feature_info);
361 AttachShader(manager, attached_shaders_[0]);
greggman 2012/06/15 08:10:24 Why do you have to attach here? Shouldn't they alr
dmurph 2012/06/19 01:08:33 Done.
362 glAttachShader(service_id(), attached_shaders_[0]->service_id());
363 AttachShader(manager, attached_shaders_[1]);
364 glAttachShader(service_id(), attached_shaders_[1]->service_id());
365 link = true;
366 break;
367 case SHADER_CACHE_LINK_SUCCEEDED:
368 fprintf(stderr, "program %i linked and cached!\n", service_id());
369 GLsizei length;
370 GLenum format;
371 const GLvoid* binary;
372 cache->getLinkedProgram(shader_a, shader_b,
373 &length, &format, &binary);
374 glProgramBinary(service_id(), format, binary, length);
375 link = false;
376 break;
377 }
378 }
379
380 if(link) {
381 glLinkProgram(service_id());
382 }
383
268 GLint success = 0; 384 GLint success = 0;
269 glGetProgramiv(service_id(), GL_LINK_STATUS, &success); 385 glGetProgramiv(service_id(), GL_LINK_STATUS, &success);
270 if (success == GL_TRUE) { 386 if (success == GL_TRUE) {
271 Update(); 387 Update();
388 if(cache && link) {
389 fprintf(stderr, "program %i just linked, caching\n", service_id());
390 GLsizei length;
391 GLenum format;
392 glGetProgramBinary(service_id(),
greggman 2012/06/15 08:10:24 This code makes no sense to me. What is cache->cac
dmurph 2012/06/15 16:40:23 Sounds good, I didn't know I could query the size
393 kShaderCacheBufferSize,
394 &length,
395 &format,
396 cache->cache_buffer());
397 fprintf(stderr, "got length of %i\n", length);
398
399 if(length != 0) {
400 GLvoid* trimedBinary = new char[length];
greggman 2012/06/15 08:10:24 Related to the above comment where does this memor
dmurph 2012/06/15 16:40:23 I like that, the memory issue was bothering me yes
401 memcpy(trimedBinary, cache->cache_buffer(), length);
402 cache->setLinkedProgram(shader_a,
403 shader_b,
404 length,
405 format,
406 trimedBinary);
407 cache->setLinkedProgramStatus(shader_a,
408 shader_b,
409 SHADER_CACHE_LINK_SUCCEEDED);
410 fprintf(stderr, "caching [%s] and [%s]\n", shader_a, shader_b);
411 }
412
413 }
272 } else { 414 } else {
273 UpdateLogInfo(); 415 UpdateLogInfo();
416 if(cache) {
417 fprintf(stderr, "program %i not linked correctly\n", service_id());
418 cache->setLinkedProgramStatus(shader_a,
419 shader_b,
420 SHADER_CACHE_LINK_UNKNOWN);
421 }
274 } 422 }
275 return success == GL_TRUE; 423 return success == GL_TRUE;
276 } 424 }
277 425
278 void ProgramManager::ProgramInfo::Validate() { 426 void ProgramManager::ProgramInfo::Validate() {
279 if (!IsValid()) { 427 if (!IsValid()) {
280 set_log_info("program not linked"); 428 set_log_info("program not linked");
281 return; 429 return;
282 } 430 }
283 glValidateProgram(service_id()); 431 glValidateProgram(service_id());
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 manager_->StopTracking(this); 824 manager_->StopTracking(this);
677 manager_ = NULL; 825 manager_ = NULL;
678 } 826 }
679 } 827 }
680 828
681 // TODO(gman): make this some kind of random number. Base::RandInt is not 829 // TODO(gman): make this some kind of random number. Base::RandInt is not
682 // callable because of the sandbox. What matters is that it's possibly different 830 // callable because of the sandbox. What matters is that it's possibly different
683 // by at least 1 bit each time chrome is run. 831 // by at least 1 bit each time chrome is run.
684 static int uniform_random_offset_ = 3; 832 static int uniform_random_offset_ = 3;
685 833
686 ProgramManager::ProgramManager() 834 ProgramManager::ProgramManager(base::WeakPtr<ShaderCache> shader_cache)
687 : uniform_swizzle_(uniform_random_offset_++ % 15), 835 : uniform_swizzle_(uniform_random_offset_++ % 15),
688 program_info_count_(0), 836 program_info_count_(0),
689 have_context_(true), 837 have_context_(true),
690 disable_workarounds_( 838 disable_workarounds_(
691 CommandLine::ForCurrentProcess()->HasSwitch( 839 CommandLine::ForCurrentProcess()->HasSwitch(
692 switches::kDisableGpuDriverBugWorkarounds)) { 840 switches::kDisableGpuDriverBugWorkarounds)),
693 } 841 shader_cache_(shader_cache){ }
694 842
695 ProgramManager::~ProgramManager() { 843 ProgramManager::~ProgramManager() {
696 DCHECK(program_infos_.empty()); 844 DCHECK(program_infos_.empty());
697 } 845 }
698 846
699 void ProgramManager::Destroy(bool have_context) { 847 void ProgramManager::Destroy(bool have_context) {
700 have_context_ = have_context; 848 have_context_ = have_context;
701 program_infos_.clear(); 849 program_infos_.clear();
702 } 850 }
703 851
(...skipping 25 matching lines...) Expand all
729 for (ProgramInfoMap::const_iterator it = program_infos_.begin(); 877 for (ProgramInfoMap::const_iterator it = program_infos_.begin();
730 it != program_infos_.end(); ++it) { 878 it != program_infos_.end(); ++it) {
731 if (it->second->service_id() == service_id) { 879 if (it->second->service_id() == service_id) {
732 *client_id = it->first; 880 *client_id = it->first;
733 return true; 881 return true;
734 } 882 }
735 } 883 }
736 return false; 884 return false;
737 } 885 }
738 886
887 ShaderCache* ProgramManager::GetShaderCache() const {
888 return shader_cache_;
889 }
890
739 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { 891 bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) {
740 for (ProgramInfoMap::iterator it = program_infos_.begin(); 892 for (ProgramInfoMap::iterator it = program_infos_.begin();
741 it != program_infos_.end(); ++it) { 893 it != program_infos_.end(); ++it) {
742 if (it->second.get() == info) { 894 if (it->second.get() == info) {
743 return true; 895 return true;
744 } 896 }
745 } 897 }
746 return false; 898 return false;
747 } 899 }
748 900
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 } 966 }
815 967
816 GLint ProgramManager::UnswizzleLocation(GLint v) const { 968 GLint ProgramManager::UnswizzleLocation(GLint v) const {
817 return v < 0 ? v : Swizzle(v - uniform_swizzle_); 969 return v < 0 ? v : Swizzle(v - uniform_swizzle_);
818 } 970 }
819 971
820 } // namespace gles2 972 } // namespace gles2
821 } // namespace gpu 973 } // namespace gpu
822 974
823 975
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698