Chromium Code Reviews| Index: gpu/command_buffer/service/program_manager.cc |
| diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc |
| index 0eb90a332a6c1d838380186cf2cabcd14580d155..20e3b4c25290b4fcecced912b364b955848727d2 100644 |
| --- a/gpu/command_buffer/service/program_manager.cc |
| +++ b/gpu/command_buffer/service/program_manager.cc |
| @@ -9,10 +9,12 @@ |
| #include <vector> |
| #include "base/basictypes.h" |
| +#include "base/bind.h" |
|
greggman
2012/06/26 23:00:27
is this include needed?
|
| #include "base/command_line.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/string_number_conversions.h" |
| +#include "net/base/net_log.h" |
|
greggman
2012/06/26 23:00:27
is this include needed?
|
| #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| @@ -283,7 +285,66 @@ void ProgramManager::ProgramInfo::ExecuteBindAttribLocationCalls() { |
| } |
| } |
| -bool ProgramManager::ProgramInfo::Link() { |
| +void ProgramManager::DoCompileShader(ShaderManager::ShaderInfo* info, |
| + ShaderTranslator* translator, |
| + FeatureInfo* feature_info) { |
| + // Translate GL ES 2.0 shader to Desktop GL shader and pass that to |
| + // glShaderSource and then glCompileShader. |
| + const char* shader_src = info->source() ? info->source()->c_str() : ""; |
| + if (translator) { |
| + if (!translator->Translate(shader_src)) { |
| + info->SetStatus(false, translator->info_log(), NULL); |
| + return; |
| + } |
| + shader_src = translator->translated_shader(); |
| + if (!feature_info->feature_flags().angle_translated_shader_source) |
|
greggman
2012/06/26 23:00:27
ugh: please add a new issue. We need to either cac
dmurph
2012/07/04 00:01:29
Hm, okay then I'll leave this alone? Should the i
|
| + info->UpdateTranslatedSource(shader_src); |
| + } |
| + |
| + glShaderSource(info->service_id(), 1, &shader_src, NULL); |
| + glCompileShader(info->service_id()); |
| + if (feature_info->feature_flags().angle_translated_shader_source) { |
| + GLint max_len = 0; |
| + glGetShaderiv(info->service_id(), |
| + GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE, |
| + &max_len); |
| + scoped_array<char> temp(new char[max_len]); |
| + GLint len = 0; |
| + glGetTranslatedShaderSourceANGLE( |
| + info->service_id(), max_len, &len, temp.get()); |
| + DCHECK(max_len == 0 || len < max_len); |
| + DCHECK(len == 0 || temp[len] == '\0'); |
| + info->UpdateTranslatedSource(temp.get()); |
| + } |
| + |
| + GLint status = GL_FALSE; |
| + glGetShaderiv(info->service_id(), GL_COMPILE_STATUS, &status); |
|
greggman
2012/06/26 23:00:27
style: I'm sure this was just copied and passed bu
dmurph
2012/07/04 00:01:29
Done.
|
| + if (status) { |
| + info->SetStatus(true, "", translator); |
| + if (program_cache_) { |
| + program_cache_->ShaderCompilationSucceeded(*info->source()); |
| + } |
| + } else { |
| + // We cannot reach here if we are using the shader translator. |
| + // All invalid shaders must be rejected by the translator. |
| + // All translated shaders must compile. |
| + LOG_IF(ERROR, translator) |
| + << "Shader translator allowed/produced an invalid shader."; |
| + GLint max_len = 0; |
| + glGetShaderiv(info->service_id(), GL_INFO_LOG_LENGTH, &max_len); |
| + scoped_array<char> temp(new char[max_len]); |
| + GLint len = 0; |
| + glGetShaderInfoLog(info->service_id(), max_len, &len, temp.get()); |
| + DCHECK(max_len == 0 || len < max_len); |
| + DCHECK(len == 0 || temp[len] == '\0'); |
| + info->SetStatus(false, std::string(temp.get(), len).c_str(), NULL); |
| + } |
| +} |
| + |
| +bool ProgramManager::ProgramInfo::Link(ShaderManager* manager, |
| + ShaderTranslator* vertex_translator, |
| + ShaderTranslator* fragment_shader, |
| + FeatureInfo* feature_info) { |
| ClearLinkStatus(); |
| if (!CanLink()) { |
| set_log_info("missing shaders"); |
| @@ -294,11 +355,64 @@ bool ProgramManager::ProgramInfo::Link() { |
| return false; |
| } |
| ExecuteBindAttribLocationCalls(); |
| - glLinkProgram(service_id()); |
| + |
| + bool link = true; |
| + ProgramCache* cache = manager_->program_cache_; |
| + const std::string* shader_a = attached_shaders_[0]->source(); |
| + const std::string* shader_b = attached_shaders_[1]->source(); |
| + if (cache) { |
| + ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( |
| + *shader_a, |
|
greggman
2012/06/26 23:00:27
style: indenting
dmurph
2012/07/04 00:01:29
Done.
|
| + *shader_b, |
| + &bind_attrib_location_map_); |
| + switch (status) { |
| + case ProgramCache::LINK_SUCCEEDED: { |
| + bool success = cache->LoadLinkedProgram(service_id(), |
| + attached_shaders_[0], |
| + attached_shaders_[1], |
| + &bind_attrib_location_map_); |
| + if (success) { |
| + link = false; |
| + break; |
| + } |
| + } // fall through |
| + case ProgramCache::LINK_UNKNOWN: |
| + // compile our shaders + attach |
| + if (attached_shaders_[0]->IsPendingCacheMissCompilation()) { |
| + manager_->DoCompileShader(attached_shaders_[0], |
|
greggman
2012/06/26 23:00:27
this code is repeated pretty much repeated twice.
dmurph
2012/07/04 00:01:29
Done.
|
| + vertex_translator, |
| + feature_info); |
| + AttachShader(manager, attached_shaders_[0]); |
| + glAttachShader(service_id(), attached_shaders_[0]->service_id()); |
| + attached_shaders_[0]->SetPendingCompilation(false); |
| + } |
| + if (attached_shaders_[1]->IsPendingCacheMissCompilation()) { |
| + manager_->DoCompileShader(attached_shaders_[1], |
| + fragment_shader, |
| + feature_info); |
| + AttachShader(manager, attached_shaders_[1]); |
| + glAttachShader(service_id(), attached_shaders_[1]->service_id()); |
| + attached_shaders_[1]->SetPendingCompilation(false); |
| + } |
| + link = true; |
| + break; |
| + } |
| + } |
| + |
| + if (link) { |
| + glLinkProgram(service_id()); |
| + } |
| + |
| GLint success = 0; |
| glGetProgramiv(service_id(), GL_LINK_STATUS, &success); |
| if (success == GL_TRUE) { |
| Update(); |
| + if (cache && link) { |
| + cache->SaveLinkedProgram(service_id(), |
| + attached_shaders_[0], |
| + attached_shaders_[1], |
| + &bind_attrib_location_map_); |
| + } |
| } else { |
| UpdateLogInfo(); |
| } |
| @@ -709,13 +823,14 @@ ProgramManager::ProgramInfo::~ProgramInfo() { |
| } |
| } |
| -ProgramManager::ProgramManager() |
| + |
| +ProgramManager::ProgramManager(ProgramCache* program_cache) |
| : program_info_count_(0), |
| have_context_(true), |
| disable_workarounds_( |
| CommandLine::ForCurrentProcess()->HasSwitch( |
| - switches::kDisableGpuDriverBugWorkarounds)) { |
| -} |
| + switches::kDisableGpuDriverBugWorkarounds)), |
| + program_cache_(program_cache) { } |
| ProgramManager::~ProgramManager() { |
| DCHECK(program_infos_.empty()); |
| @@ -761,6 +876,10 @@ bool ProgramManager::GetClientId(GLuint service_id, GLuint* client_id) const { |
| return false; |
| } |
| +ProgramCache* ProgramManager::program_cache() const { |
| + return program_cache_; |
| +} |
| + |
| bool ProgramManager::IsOwned(ProgramManager::ProgramInfo* info) { |
| for (ProgramInfoMap::iterator it = program_infos_.begin(); |
| it != program_infos_.end(); ++it) { |