diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-17 19:51:09 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-17 19:51:09 +0000 |
commit | ef2e2ab86b5e3ce42c1692d07ae8b8cc6fa22e2d (patch) | |
tree | 65538213d931e6d25fb5d0522fe77af496e8647f /gpu | |
parent | 2d92abb6e9b343499b469416e5b60b46ee0d9e00 (diff) | |
download | chromium_src-ef2e2ab86b5e3ce42c1692d07ae8b8cc6fa22e2d.zip chromium_src-ef2e2ab86b5e3ce42c1692d07ae8b8cc6fa22e2d.tar.gz chromium_src-ef2e2ab86b5e3ce42c1692d07ae8b8cc6fa22e2d.tar.bz2 |
Make shader translator options effect cache key
BUG=240898
Review URL: https://chromiumcodereview.appspot.com/15038009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200870 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/memory_program_cache.cc | 16 | ||||
-rw-r--r-- | gpu/command_buffer/service/memory_program_cache.h | 4 | ||||
-rw-r--r-- | gpu/command_buffer/service/memory_program_cache_unittest.cc | 73 | ||||
-rw-r--r-- | gpu/command_buffer/service/mocks.h | 10 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache.cc | 36 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache.h | 20 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_cache_unittest.cc | 141 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_manager.cc | 13 | ||||
-rw-r--r-- | gpu/command_buffer/service/program_manager_unittest.cc | 20 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator.cc | 73 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator.h | 9 | ||||
-rw-r--r-- | gpu/command_buffer/service/shader_translator_unittest.cc | 37 |
12 files changed, 349 insertions, 103 deletions
diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc index d9d944d..2582a49 100644 --- a/gpu/command_buffer/service/memory_program_cache.cc +++ b/gpu/command_buffer/service/memory_program_cache.cc @@ -107,13 +107,17 @@ void MemoryProgramCache::ClearBackend() { ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( GLuint program, Shader* shader_a, + const ShaderTranslatorInterface* translator_a, Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) const { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha); - ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha); + ComputeShaderHash( + *shader_a->deferred_compilation_source(), translator_a, a_sha); + ComputeShaderHash( + *shader_b->deferred_compilation_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -160,7 +164,9 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram( void MemoryProgramCache::SaveLinkedProgram( GLuint program, const Shader* shader_a, + const ShaderTranslatorInterface* translator_a, const Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) { GLenum format; @@ -179,8 +185,10 @@ void MemoryProgramCache::SaveLinkedProgram( char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(*shader_a->deferred_compilation_source(), a_sha); - ComputeShaderHash(*shader_b->deferred_compilation_source(), b_sha); + ComputeShaderHash( + *shader_a->deferred_compilation_source(), translator_a, a_sha); + ComputeShaderHash( + *shader_b->deferred_compilation_source(), translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, diff --git a/gpu/command_buffer/service/memory_program_cache.h b/gpu/command_buffer/service/memory_program_cache.h index 7d5f808..ed791a8 100644 --- a/gpu/command_buffer/service/memory_program_cache.h +++ b/gpu/command_buffer/service/memory_program_cache.h @@ -29,13 +29,17 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache { virtual ProgramLoadResult LoadLinkedProgram( GLuint program, Shader* shader_a, + const ShaderTranslatorInterface* translator_a, Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) const OVERRIDE; virtual void SaveLinkedProgram( GLuint program, const Shader* shader_a, + const ShaderTranslatorInterface* translator_a, const Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) OVERRIDE; diff --git a/gpu/command_buffer/service/memory_program_cache_unittest.cc b/gpu/command_buffer/service/memory_program_cache_unittest.cc index b083552..603c21e 100644 --- a/gpu/command_buffer/service/memory_program_cache_unittest.cc +++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc @@ -96,8 +96,8 @@ class MemoryProgramCacheTest : public testing::Test { ::gfx::GLInterface::SetGLInterface(gl_.get()); vertex_shader_ = shader_manager_.CreateShader(kVertexShaderClientId, - kVertexShaderServiceId, - GL_VERTEX_SHADER); + kVertexShaderServiceId, + GL_VERTEX_SHADER); fragment_shader_ = shader_manager_.CreateShader( kFragmentShaderClientId, kFragmentShaderServiceId, @@ -196,13 +196,16 @@ TEST_F(MemoryProgramCacheTest, CacheSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); } @@ -218,13 +221,16 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); EXPECT_EQ(1, shader_cache_count()); @@ -233,7 +239,9 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) { cache_->LoadProgram(shader_cache_shader()); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); } @@ -248,7 +256,8 @@ TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(1, shader_cache_count()); @@ -268,8 +277,10 @@ TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -294,7 +305,8 @@ TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(1, shader_cache_count()); @@ -317,8 +329,10 @@ TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -343,7 +357,8 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -351,8 +366,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -368,7 +385,8 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -379,8 +397,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); @@ -391,8 +411,10 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -412,7 +434,9 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) { binding_map["test"] = 512; cache_->SaveLinkedProgram(kProgramId, vertex_shader_, + NULL, fragment_shader_, + NULL, &binding_map, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -421,15 +445,19 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, + NULL, &binding_map, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -447,7 +475,8 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -472,18 +501,24 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) { SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2); cache_->SaveLinkedProgram(kEvictingProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus( old_source, + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); } @@ -499,13 +534,16 @@ TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) { vertex_shader_->UpdateSource("different!"); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); } @@ -520,13 +558,16 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus( *vertex_shader_->deferred_compilation_source(), + NULL, *fragment_shader_->deferred_compilation_source(), + NULL, NULL)); SetExpectationsForLoadLinkedProgram(kProgramId, &emulator); @@ -535,8 +576,10 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } @@ -552,7 +595,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -563,7 +607,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { } ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2); SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2); - cache_->SaveLinkedProgram(kProgramId, vertex_shader_, fragment_shader_, NULL, + cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL, + fragment_shader_, NULL, NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this))); @@ -571,8 +616,10 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) { EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram( kProgramId, vertex_shader_, + NULL, fragment_shader_, NULL, + NULL, base::Bind(&MemoryProgramCacheTest::ShaderCacheCb, base::Unretained(this)))); } diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h index 0964ada..11b8ae6 100644 --- a/gpu/command_buffer/service/mocks.h +++ b/gpu/command_buffer/service/mocks.h @@ -91,6 +91,8 @@ class MockShaderTranslator : public ShaderTranslatorInterface { MOCK_CONST_METHOD0(attrib_map, const VariableMap&()); MOCK_CONST_METHOD0(uniform_map, const VariableMap&()); MOCK_CONST_METHOD0(name_map, const NameMap&()); + MOCK_CONST_METHOD0( + GetStringForOptionsThatWouldEffectCompilation, std::string()); }; class MockProgramCache : public ProgramCache { @@ -98,17 +100,21 @@ class MockProgramCache : public ProgramCache { MockProgramCache(); virtual ~MockProgramCache(); - MOCK_CONST_METHOD5(LoadLinkedProgram, ProgramLoadResult( + MOCK_CONST_METHOD7(LoadLinkedProgram, ProgramLoadResult( GLuint program, Shader* shader_a, + const ShaderTranslatorInterface* translator_a, Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& callback)); - MOCK_METHOD5(SaveLinkedProgram, void( + MOCK_METHOD7(SaveLinkedProgram, void( GLuint program, const Shader* shader_a, + const ShaderTranslatorInterface* translator_a, const Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& callback)); MOCK_METHOD1(LoadProgram, void(const std::string&)); diff --git a/gpu/command_buffer/service/program_cache.cc b/gpu/command_buffer/service/program_cache.cc index 48fafab..62e636d 100644 --- a/gpu/command_buffer/service/program_cache.cc +++ b/gpu/command_buffer/service/program_cache.cc @@ -4,6 +4,7 @@ #include "gpu/command_buffer/service/program_cache.h" +#include <string> #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/service/shader_manager.h" @@ -20,9 +21,10 @@ void ProgramCache::Clear() { } ProgramCache::CompiledShaderStatus ProgramCache::GetShaderCompilationStatus( - const std::string& shader_src) const { + const std::string& shader_src, + const ShaderTranslatorInterface* translator) const { char sha[kHashLength]; - ComputeShaderHash(shader_src, sha); + ComputeShaderHash(shader_src, translator, sha); const std::string sha_string(sha, kHashLength); CompileStatusMap::const_iterator found = shader_status_.find(sha_string); @@ -35,9 +37,10 @@ ProgramCache::CompiledShaderStatus ProgramCache::GetShaderCompilationStatus( } void ProgramCache::ShaderCompilationSucceeded( - const std::string& shader_src) { + const std::string& shader_src, + const ShaderTranslatorInterface* translator) { char sha[kHashLength]; - ComputeShaderHash(shader_src, sha); + ComputeShaderHash(shader_src, translator, sha); const std::string sha_string(sha, kHashLength); ShaderCompilationSucceededSha(sha_string); } @@ -54,12 +57,14 @@ void ProgramCache::ShaderCompilationSucceededSha( ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus( const std::string& untranslated_a, + const ShaderTranslatorInterface* translator_a, const std::string& untranslated_b, + const ShaderTranslatorInterface* translator_b, const std::map<std::string, GLint>* bind_attrib_location_map) const { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(untranslated_a, a_sha); - ComputeShaderHash(untranslated_b, b_sha); + ComputeShaderHash(untranslated_a, translator_a, a_sha); + ComputeShaderHash(untranslated_b, translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -78,12 +83,14 @@ ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus( void ProgramCache::LinkedProgramCacheSuccess( const std::string& shader_a, + const ShaderTranslatorInterface* translator_a, const std::string& shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map) { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(shader_a, a_sha); - ComputeShaderHash(shader_b, b_sha); + ComputeShaderHash(shader_a, translator_a, a_sha); + ComputeShaderHash(shader_b, translator_b, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, b_sha, @@ -104,10 +111,15 @@ void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash, shader_status_[shader_b_hash].ref_count++; } -void ProgramCache::ComputeShaderHash(const std::string& str, - char* result) const { - base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()), - str.length(), reinterpret_cast<unsigned char*>(result)); +void ProgramCache::ComputeShaderHash( + const std::string& str, + const ShaderTranslatorInterface* translator, + char* result) const { + std::string s(( + translator ? translator->GetStringForOptionsThatWouldEffectCompilation() : + std::string()) + str); + base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(s.c_str()), + s.length(), reinterpret_cast<unsigned char*>(result)); } void ProgramCache::Evict(const std::string& program_hash, diff --git a/gpu/command_buffer/service/program_cache.h b/gpu/command_buffer/service/program_cache.h index c4b50e8..c42d359 100644 --- a/gpu/command_buffer/service/program_cache.h +++ b/gpu/command_buffer/service/program_cache.h @@ -18,6 +18,7 @@ namespace gpu { namespace gles2 { class Shader; +class ShaderTranslator; // Program cache base class for caching linked gpu programs class GPU_EXPORT ProgramCache { @@ -45,13 +46,17 @@ class GPU_EXPORT ProgramCache { virtual ~ProgramCache(); CompiledShaderStatus GetShaderCompilationStatus( - const std::string& shader_src) const; - void ShaderCompilationSucceeded(const std::string& shader_src); + const std::string& shader_src, + const ShaderTranslatorInterface* translator) const; + void ShaderCompilationSucceeded(const std::string& shader_src, + const ShaderTranslatorInterface* translator); void ShaderCompilationSucceededSha(const std::string& sha_string); LinkedProgramStatus GetLinkedProgramStatus( - const std::string& untranslated_a, - const std::string& untranslated_b, + const std::string& untranslated_shader_a, + const ShaderTranslatorInterface* translator_a, + const std::string& untranslated_shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map) const; // Loads the linked program from the cache. If the program is not found or @@ -59,7 +64,9 @@ class GPU_EXPORT ProgramCache { virtual ProgramLoadResult LoadLinkedProgram( GLuint program, Shader* shader_a, + const ShaderTranslatorInterface* translator_a, Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) const = 0; @@ -68,7 +75,9 @@ class GPU_EXPORT ProgramCache { virtual void SaveLinkedProgram( GLuint program, const Shader* shader_a, + const ShaderTranslatorInterface* translator_a, const Shader* shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map, const ShaderCacheCallback& shader_callback) = 0; @@ -79,7 +88,9 @@ class GPU_EXPORT ProgramCache { // Only for testing void LinkedProgramCacheSuccess(const std::string& shader_a, + const ShaderTranslatorInterface* translator_a, const std::string& shader_b, + const ShaderTranslatorInterface* translator_b, const LocationMap* bind_attrib_location_map); protected: @@ -90,6 +101,7 @@ class GPU_EXPORT ProgramCache { // result is not null terminated void ComputeShaderHash(const std::string& shader, + const ShaderTranslatorInterface* translator, char* result) const; // result is not null terminated. hashed shaders are expected to be diff --git a/gpu/command_buffer/service/program_cache_unittest.cc b/gpu/command_buffer/service/program_cache_unittest.cc index 46a2fe1..63c032d 100644 --- a/gpu/command_buffer/service/program_cache_unittest.cc +++ b/gpu/command_buffer/service/program_cache_unittest.cc @@ -5,8 +5,11 @@ #include "gpu/command_buffer/service/program_cache.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/service/mocks.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::Return; + namespace gpu { namespace gles2 { @@ -15,7 +18,9 @@ class NoBackendProgramCache : public ProgramCache { virtual ProgramLoadResult LoadLinkedProgram( GLuint /* program */, Shader* /* shader_a */, + const ShaderTranslatorInterface* /* translator_a */, Shader* /* shader_b */, + const ShaderTranslatorInterface* /* translator_b */, const LocationMap* /* bind_attrib_location_map */, const ShaderCacheCallback& /* callback */) const OVERRIDE { return PROGRAM_LOAD_SUCCESS; @@ -23,7 +28,9 @@ class NoBackendProgramCache : public ProgramCache { virtual void SaveLinkedProgram( GLuint /* program */, const Shader* /* shader_a */, + const ShaderTranslatorInterface* /* translator_b */, const Shader* /* shader_b */, + const ShaderTranslatorInterface* /* translator_b */, const LocationMap* /* bind_attrib_location_map */, const ShaderCacheCallback& /* callback */) OVERRIDE { } @@ -32,12 +39,14 @@ class NoBackendProgramCache : public ProgramCache { virtual void ClearBackend() OVERRIDE {} void SaySuccessfullyCached(const std::string& shader1, + const ShaderTranslatorInterface* translator_1, const std::string& shader2, + const ShaderTranslatorInterface* translator_2, std::map<std::string, GLint>* attrib_map) { char a_sha[kHashLength]; char b_sha[kHashLength]; - ComputeShaderHash(shader1, a_sha); - ComputeShaderHash(shader2, b_sha); + ComputeShaderHash(shader1, translator_1, a_sha); + ComputeShaderHash(shader2, translator_2, b_sha); char sha[kHashLength]; ComputeProgramHash(a_sha, @@ -52,8 +61,9 @@ class NoBackendProgramCache : public ProgramCache { } void ComputeShaderHash(const std::string& shader, + const ShaderTranslatorInterface* translator, char* result) const { - ProgramCache::ComputeShaderHash(shader, result); + ProgramCache::ComputeShaderHash(shader, translator, result); } void ComputeProgramHash(const char* hashed_shader_0, @@ -87,22 +97,47 @@ TEST_F(ProgramCacheTest, CompilationStatusSave) { { std::string shader = shader1; EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader)); - cache_->ShaderCompilationSucceeded(shader); + cache_->GetShaderCompilationStatus(shader, NULL)); + cache_->ShaderCompilationSucceeded(shader, NULL); + shader.clear(); + } + // make sure it was copied + EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, + cache_->GetShaderCompilationStatus(shader1, NULL)); +} + +TEST_F(ProgramCacheTest, CompilationStatusTranslatorOptionDependent) { + MockShaderTranslator translator; + + EXPECT_CALL(translator, GetStringForOptionsThatWouldEffectCompilation()) + .WillOnce(Return("foo")) // GetShaderCompilationStatus + .WillOnce(Return("foo")) // ShaderCompilationSucceeded + .WillOnce(Return("foo")) // GetShaderCompilationStatus + .WillOnce(Return("bar")); // GetShaderCompilationStatus + + const std::string shader1 = "abcd1234"; + { + std::string shader = shader1; + EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, + cache_->GetShaderCompilationStatus(shader, &translator)); + cache_->ShaderCompilationSucceeded(shader, &translator); shader.clear(); } // make sure it was copied EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, &translator)); + // make sure if the options change it's not copied. + EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, + cache_->GetShaderCompilationStatus(shader1, &translator)); } TEST_F(ProgramCacheTest, CompilationUnknownOnSourceChange) { std::string shader1 = "abcd1234"; - cache_->ShaderCompilationSucceeded(shader1); + cache_->ShaderCompilationSucceeded(shader1, NULL); shader1 = "different!"; EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, NULL)); } TEST_F(ProgramCacheTest, LinkStatusSave) { @@ -112,47 +147,49 @@ TEST_F(ProgramCacheTest, LinkStatusSave) { std::string shader_a = shader1; std::string shader_b = shader2; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader_a, shader_b, NULL)); - cache_->SaySuccessfullyCached(shader_a, shader_b, NULL); + cache_->GetLinkedProgramStatus( + shader_a, NULL, shader_b, NULL, NULL)); + cache_->SaySuccessfullyCached(shader_a, NULL, shader_b, NULL, NULL); shader_a.clear(); shader_b.clear(); } // make sure it was copied EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus( + shader1, NULL, shader2, NULL, NULL)); } TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) { const std::string shader1 = "abcd1234"; std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->SaySuccessfullyCached(shader1, shader2, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); shader2 = "different!"; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); } TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) { std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->SaySuccessfullyCached(shader1, shader2, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); shader1 = "different!"; EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); } TEST_F(ProgramCacheTest, StatusEviction) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; - cache_->ShaderCompilationSucceeded(shader1); - cache_->ShaderCompilationSucceeded(shader2); - cache_->SaySuccessfullyCached(shader1, shader2, NULL); + cache_->ShaderCompilationSucceeded(shader1, NULL); + cache_->ShaderCompilationSucceeded(shader2, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); char a_sha[ProgramCache::kHashLength]; char b_sha[ProgramCache::kHashLength]; - cache_->ComputeShaderHash(shader1, a_sha); - cache_->ComputeShaderHash(shader2, b_sha); + cache_->ComputeShaderHash(shader1, NULL, a_sha); + cache_->ComputeShaderHash(shader2, NULL, b_sha); char sha[ProgramCache::kHashLength]; cache_->ComputeProgramHash(a_sha, @@ -163,30 +200,30 @@ TEST_F(ProgramCacheTest, StatusEviction) { std::string(a_sha, ProgramCache::kHashLength), std::string(b_sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2)); + cache_->GetShaderCompilationStatus(shader2, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); } TEST_F(ProgramCacheTest, EvictionWithReusedShader) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->ShaderCompilationSucceeded(shader1); - cache_->ShaderCompilationSucceeded(shader2); - cache_->SaySuccessfullyCached(shader1, shader2, NULL); - cache_->ShaderCompilationSucceeded(shader1); - cache_->ShaderCompilationSucceeded(shader3); - cache_->SaySuccessfullyCached(shader1, shader3, NULL); + cache_->ShaderCompilationSucceeded(shader1, NULL); + cache_->ShaderCompilationSucceeded(shader2, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); + cache_->ShaderCompilationSucceeded(shader1, NULL); + cache_->ShaderCompilationSucceeded(shader3, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); char a_sha[ProgramCache::kHashLength]; char b_sha[ProgramCache::kHashLength]; char c_sha[ProgramCache::kHashLength]; - cache_->ComputeShaderHash(shader1, a_sha); - cache_->ComputeShaderHash(shader2, b_sha); - cache_->ComputeShaderHash(shader3, c_sha); + cache_->ComputeShaderHash(shader1, NULL, a_sha); + cache_->ComputeShaderHash(shader2, NULL, b_sha); + cache_->ComputeShaderHash(shader3, NULL, c_sha); char sha[ProgramCache::kHashLength]; cache_->ComputeProgramHash(a_sha, @@ -197,15 +234,15 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) { std::string(a_sha, ProgramCache::kHashLength), std::string(b_sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2)); + cache_->GetShaderCompilationStatus(shader2, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(shader3)); + cache_->GetShaderCompilationStatus(shader3, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, - cache_->GetLinkedProgramStatus(shader1, shader3, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); cache_->ComputeProgramHash(a_sha, @@ -216,37 +253,37 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) { std::string(a_sha, ProgramCache::kHashLength), std::string(c_sha, ProgramCache::kHashLength)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2)); + cache_->GetShaderCompilationStatus(shader2, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader3)); + cache_->GetShaderCompilationStatus(shader3, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader3, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); } TEST_F(ProgramCacheTest, StatusClear) { const std::string shader1 = "abcd1234"; const std::string shader2 = "abcda sda b1~#4 bbbbb1234"; const std::string shader3 = "asbjbbjj239a"; - cache_->ShaderCompilationSucceeded(shader1); - cache_->ShaderCompilationSucceeded(shader2); - cache_->SaySuccessfullyCached(shader1, shader2, NULL); - cache_->ShaderCompilationSucceeded(shader3); - cache_->SaySuccessfullyCached(shader1, shader3, NULL); + cache_->ShaderCompilationSucceeded(shader1, NULL); + cache_->ShaderCompilationSucceeded(shader2, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL); + cache_->ShaderCompilationSucceeded(shader3, NULL); + cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL); cache_->Clear(); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader1)); + cache_->GetShaderCompilationStatus(shader1, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader2)); + cache_->GetShaderCompilationStatus(shader2, NULL)); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(shader3)); + cache_->GetShaderCompilationStatus(shader3, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader2, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL)); EXPECT_EQ(ProgramCache::LINK_UNKNOWN, - cache_->GetLinkedProgramStatus(shader1, shader3, NULL)); + cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL)); } } // namespace gles2 diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc index 5d3c3a2..d362cde 100644 --- a/gpu/command_buffer/service/program_manager.cc +++ b/gpu/command_buffer/service/program_manager.cc @@ -446,8 +446,8 @@ void ProgramManager::DoCompileShader(Shader* shader, TimeTicks before = TimeTicks::HighResNow(); if (program_cache_ && program_cache_->GetShaderCompilationStatus( - shader->source() ? *shader->source() : std::string()) == - ProgramCache::COMPILATION_SUCCEEDED) { + shader->source() ? *shader->source() : std::string(), + translator) == ProgramCache::COMPILATION_SUCCEEDED) { shader->SetStatus(true, "", translator); shader->FlagSourceAsCompiled(false); UMA_HISTOGRAM_CUSTOM_COUNTS( @@ -508,7 +508,8 @@ void ProgramManager::ForceCompileShader(const std::string* source, shader->SetStatus(true, "", translator); if (program_cache_) { const char* untranslated_source = source ? source->c_str() : ""; - program_cache_->ShaderCompilationSucceeded(untranslated_source); + program_cache_->ShaderCompilationSucceeded( + untranslated_source, translator); } } else { // We cannot reach here if we are using the shader translator. @@ -552,14 +553,18 @@ bool Program::Link(ShaderManager* manager, if (cache) { ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus( *attached_shaders_[0]->deferred_compilation_source(), + vertex_translator, *attached_shaders_[1]->deferred_compilation_source(), + fragment_translator, &bind_attrib_location_map_); if (status == ProgramCache::LINK_SUCCEEDED) { ProgramCache::ProgramLoadResult success = cache->LoadLinkedProgram( service_id(), attached_shaders_[0], + vertex_translator, attached_shaders_[1], + fragment_translator, &bind_attrib_location_map_, shader_callback); link = success != ProgramCache::PROGRAM_LOAD_SUCCESS; @@ -606,7 +611,9 @@ bool Program::Link(ShaderManager* manager, if (cache) { cache->SaveLinkedProgram(service_id(), attached_shaders_[0], + vertex_translator, attached_shaders_[1], + fragment_translator, &bind_attrib_location_map_, shader_callback); } diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc index 8770e93..fce5ac3 100644 --- a/gpu/command_buffer/service/program_manager_unittest.cc +++ b/gpu/command_buffer/service/program_manager_unittest.cc @@ -1192,8 +1192,8 @@ class ProgramManagerWithCacheTest : public testing::Test { } void SetShadersCompiled() { - cache_->ShaderCompilationSucceeded(*vertex_shader_->source()); - cache_->ShaderCompilationSucceeded(*fragment_shader_->source()); + cache_->ShaderCompilationSucceeded(*vertex_shader_->source(), NULL); + cache_->ShaderCompilationSucceeded(*fragment_shader_->source(), NULL); vertex_shader_->SetStatus(true, NULL, NULL); fragment_shader_->SetStatus(true, NULL, NULL); vertex_shader_->FlagSourceAsCompiled(true); @@ -1209,7 +1209,9 @@ class ProgramManagerWithCacheTest : public testing::Test { void SetProgramCached() { cache_->LinkedProgramCacheSuccess( vertex_shader_->source()->c_str(), + NULL, fragment_shader_->source()->c_str(), + NULL, &program_->bind_attrib_location_map()); } @@ -1226,7 +1228,9 @@ class ProgramManagerWithCacheTest : public testing::Test { EXPECT_CALL(*cache_.get(), SaveLinkedProgram( program->service_id(), vertex_shader, + NULL, fragment_shader, + NULL, &program->bind_attrib_location_map(), _)).Times(1); } @@ -1244,7 +1248,9 @@ class ProgramManagerWithCacheTest : public testing::Test { EXPECT_CALL(*cache_.get(), SaveLinkedProgram( program->service_id(), vertex_shader, + NULL, fragment_shader, + NULL, &program->bind_attrib_location_map(), _)).Times(0); } @@ -1266,7 +1272,9 @@ class ProgramManagerWithCacheTest : public testing::Test { EXPECT_CALL(*cache_.get(), LoadLinkedProgram(service_program_id, vertex_shader, + NULL, fragment_shader, + NULL, &program->bind_attrib_location_map(), _)) .WillOnce(Return(result)); @@ -1360,7 +1368,8 @@ TEST_F(ProgramManagerWithCacheTest, CacheSuccessAfterShaderCompile) { scoped_refptr<FeatureInfo> info(new FeatureInfo()); manager_.DoCompileShader(vertex_shader_, NULL, info.get()); EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, - cache_->GetShaderCompilationStatus(*vertex_shader_->source())); + cache_->GetShaderCompilationStatus( + *vertex_shader_->source(), NULL)); } TEST_F(ProgramManagerWithCacheTest, CacheUnknownAfterShaderError) { @@ -1368,11 +1377,12 @@ TEST_F(ProgramManagerWithCacheTest, CacheUnknownAfterShaderError) { scoped_refptr<FeatureInfo> info(new FeatureInfo()); manager_.DoCompileShader(vertex_shader_, NULL, info.get()); EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, - cache_->GetShaderCompilationStatus(*vertex_shader_->source())); + cache_->GetShaderCompilationStatus( + *vertex_shader_->source(), NULL)); } TEST_F(ProgramManagerWithCacheTest, NoCompileWhenShaderCached) { - cache_->ShaderCompilationSucceeded(vertex_shader_->source()->c_str()); + cache_->ShaderCompilationSucceeded(vertex_shader_->source()->c_str(), NULL); SetExpectationsForNoCompile(vertex_shader_); scoped_refptr<FeatureInfo> info(new FeatureInfo()); manager_.DoCompileShader(vertex_shader_, NULL, info.get()); diff --git a/gpu/command_buffer/service/shader_translator.cc b/gpu/command_buffer/service/shader_translator.cc index 2e5541d..423681a 100644 --- a/gpu/command_buffer/service/shader_translator.cc +++ b/gpu/command_buffer/service/shader_translator.cc @@ -9,6 +9,7 @@ #include "base/at_exit.h" #include "base/logging.h" +#include "base/strings/string_number_conversions.h" namespace { @@ -139,19 +140,14 @@ bool ShaderTranslator::Init( compiler_ = ShConstructCompiler( shader_type, shader_spec, shader_output, resources); + compiler_options_ = *resources; implementation_is_glsl_es_ = (glsl_implementation_type == kGlslES); needs_built_in_function_emulation_ = (glsl_built_in_function_behavior == kGlslBuiltInFunctionEmulated); return compiler_ != NULL; } -bool ShaderTranslator::Translate(const char* shader) { - // Make sure this instance is initialized. - DCHECK(compiler_ != NULL); - DCHECK(shader != NULL); - ClearResults(); - - bool success = false; +int ShaderTranslator::GetCompileOptions() const { int compile_options = SH_OBJECT_CODE | SH_ATTRIBUTES_UNIFORMS | SH_MAP_LONG_VARIABLE_NAMES | SH_ENFORCE_PACKING_RESTRICTIONS; @@ -160,7 +156,18 @@ bool ShaderTranslator::Translate(const char* shader) { if (needs_built_in_function_emulation_) compile_options |= SH_EMULATE_BUILT_IN_FUNCTIONS; - if (ShCompile(compiler_, &shader, 1, compile_options)) { + + return compile_options; +} + +bool ShaderTranslator::Translate(const char* shader) { + // Make sure this instance is initialized. + DCHECK(compiler_ != NULL); + DCHECK(shader != NULL); + ClearResults(); + + bool success = false; + if (ShCompile(compiler_, &shader, 1, GetCompileOptions())) { success = true; // Get translated shader. ANGLEGetInfoType obj_code_len = 0; @@ -189,6 +196,56 @@ bool ShaderTranslator::Translate(const char* shader) { return success; } +std::string ShaderTranslator::GetStringForOptionsThatWouldEffectCompilation() + const { + const size_t kNumIntFields = 13; + const size_t kNumEnumFields = 1; + const size_t kNumFunctionPointerFields = 1; + struct MustMatchShBuiltInResource { + typedef khronos_uint64_t (*FunctionPointer)(const char*, size_t); + enum Enum { + kFirst, + }; + int int_fields[kNumIntFields]; + FunctionPointer pointer_fields[kNumFunctionPointerFields]; + Enum enum_fields[kNumEnumFields]; + }; + // If this assert fails most likely that means something below needs updating. + COMPILE_ASSERT( + sizeof(ShBuiltInResources) == sizeof(MustMatchShBuiltInResource), + Fields_Have_Changed_In_ShBuiltInResource_So_Update_Below); + + return std::string( + ":CompileOptions:" + + base::IntToString(GetCompileOptions()) + + ":MaxVertexAttribs:" + + base::IntToString(compiler_options_.MaxVertexAttribs) + + ":MaxVertexUniformVectors:" + + base::IntToString(compiler_options_.MaxVertexUniformVectors) + + ":MaxVaryingVectors:" + + base::IntToString(compiler_options_.MaxVaryingVectors) + + ":MaxVertexTextureImageUnits:" + + base::IntToString(compiler_options_.MaxVertexTextureImageUnits) + + ":MaxCombinedTextureImageUnits:" + + base::IntToString(compiler_options_.MaxCombinedTextureImageUnits) + + ":MaxTextureImageUnits:" + + base::IntToString(compiler_options_.MaxTextureImageUnits) + + ":MaxFragmentUniformVectors:" + + base::IntToString(compiler_options_.MaxFragmentUniformVectors) + + ":MaxDrawBuffers:" + + base::IntToString(compiler_options_.MaxDrawBuffers) + + ":OES_standard_derivatives:" + + base::IntToString(compiler_options_.OES_standard_derivatives) + + ":OES_EGL_image_external:" + + base::IntToString(compiler_options_.OES_EGL_image_external) + + ":ARB_texture_rectangle:" + + base::IntToString(compiler_options_.ARB_texture_rectangle) + + ":EXT_draw_buffers:" + + base::IntToString(compiler_options_.EXT_draw_buffers) + + ":FragmentPrecisionHigh:" + + base::IntToString(compiler_options_.FragmentPrecisionHigh)); +} + const char* ShaderTranslator::translated_shader() const { return translated_shader_.get(); } diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h index 9260171..5904f73 100644 --- a/gpu/command_buffer/service/shader_translator.h +++ b/gpu/command_buffer/service/shader_translator.h @@ -84,6 +84,10 @@ class ShaderTranslatorInterface { virtual const VariableMap& uniform_map() const = 0; virtual const NameMap& name_map() const = 0; + // Return a string that is unique for a specfic set of options that would + // possibly effect compilation. + virtual std::string GetStringForOptionsThatWouldEffectCompilation() const = 0; + protected: virtual ~ShaderTranslatorInterface() {} }; @@ -126,6 +130,9 @@ class GPU_EXPORT ShaderTranslator virtual const VariableMap& uniform_map() const OVERRIDE; virtual const NameMap& name_map() const OVERRIDE; + virtual std::string GetStringForOptionsThatWouldEffectCompilation() const + OVERRIDE; + void AddDestructionObserver(DestructionObserver* observer); void RemoveDestructionObserver(DestructionObserver* observer); @@ -134,8 +141,10 @@ class GPU_EXPORT ShaderTranslator virtual ~ShaderTranslator(); void ClearResults(); + int GetCompileOptions() const; ShHandle compiler_; + ShBuiltInResources compiler_options_; scoped_ptr<char[]> translated_shader_; scoped_ptr<char[]> info_log_; VariableMap attrib_map_; diff --git a/gpu/command_buffer/service/shader_translator_unittest.cc b/gpu/command_buffer/service/shader_translator_unittest.cc index 469028d..08d54c5 100644 --- a/gpu/command_buffer/service/shader_translator_unittest.cc +++ b/gpu/command_buffer/service/shader_translator_unittest.cc @@ -219,6 +219,43 @@ TEST_F(ShaderTranslatorTest, BuiltInFunctionEmulation) { } #endif +TEST_F(ShaderTranslatorTest, OptionsString) { + scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator(); + scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator(); + scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator(); + + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + + ASSERT_TRUE(translator_1->Init( + SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated)); + ASSERT_TRUE(translator_2->Init( + SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal)); + resources.EXT_draw_buffers = 1; + ASSERT_TRUE(translator_3->Init( + SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources, + ShaderTranslatorInterface::kGlsl, + ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated)); + + std::string options_1( + translator_1->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_2( + translator_1->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_3( + translator_2->GetStringForOptionsThatWouldEffectCompilation()); + std::string options_4( + translator_3->GetStringForOptionsThatWouldEffectCompilation()); + + EXPECT_EQ(options_1, options_2); + EXPECT_NE(options_1, options_3); + EXPECT_NE(options_1, options_4); + EXPECT_NE(options_3, options_4); +} + } // namespace gles2 } // namespace gpu |