summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authordyen <dyen@chromium.org>2015-02-12 14:27:43 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-12 22:28:49 +0000
commit0ff9e4405e9b91c0a2ca4a18a382ba6dd0d6f934 (patch)
tree1be7f8df87f1cd3de89bdaa27e2405858c77c3c6 /gpu
parent5d118a6b1d6a6b5c7325a16c2f9ac6187cd5918d (diff)
downloadchromium_src-0ff9e4405e9b91c0a2ca4a18a382ba6dd0d6f934.zip
chromium_src-0ff9e4405e9b91c0a2ca4a18a382ba6dd0d6f934.tar.gz
chromium_src-0ff9e4405e9b91c0a2ca4a18a382ba6dd0d6f934.tar.bz2
Shader compiles deferred until program link time after a cache miss.
Shader compiles are now deferred until glLinkProgram() or until an status is queried from glGetShaderiv() which requires compilation information. Additionally, the shader cache is now checked first before the shader gets compiled. That way, if the shader is in the cache it will skip the compilation step altogether. BUG=450690 TEST=trybots Review URL: https://codereview.chromium.org/894973004 Cr-Commit-Position: refs/heads/master@{#316064}
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc55
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc18
-rw-r--r--gpu/command_buffer/service/memory_program_cache.cc13
-rw-r--r--gpu/command_buffer/service/memory_program_cache.h5
-rw-r--r--gpu/command_buffer/service/memory_program_cache_unittest.cc110
-rw-r--r--gpu/command_buffer/service/mocks.h11
-rw-r--r--gpu/command_buffer/service/program_cache.cc28
-rw-r--r--gpu/command_buffer/service/program_cache.h18
-rw-r--r--gpu/command_buffer/service/program_cache_unittest.cc61
-rw-r--r--gpu/command_buffer/service/program_manager.cc107
-rw-r--r--gpu/command_buffer/service/program_manager.h5
-rw-r--r--gpu/command_buffer/service/program_manager_unittest.cc30
-rw-r--r--gpu/command_buffer/service/shader_manager.cc12
-rw-r--r--gpu/command_buffer/service/shader_manager.h22
-rw-r--r--gpu/command_buffer/service/shader_manager_unittest.cc6
-rw-r--r--gpu/command_buffer/service/shader_translator.h16
-rw-r--r--gpu/command_buffer/service/test_helper.cc21
-rw-r--r--gpu/command_buffer/tests/gl_program_unittest.cc64
-rw-r--r--gpu/command_buffer/tests/gl_test_utils.cc18
-rw-r--r--gpu/command_buffer/tests/gl_test_utils.h12
21 files changed, 346 insertions, 288 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index aefe979..aab35a4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1825,8 +1825,8 @@ class GLES2DecoderImpl : public GLES2Decoder,
error::Error current_decoder_error_;
bool use_shader_translator_;
- scoped_refptr<ShaderTranslator> vertex_translator_;
- scoped_refptr<ShaderTranslator> fragment_translator_;
+ scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
+ scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
DisallowedFeatures disallowed_features_;
@@ -5842,15 +5842,7 @@ void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
}
LogClientServiceForInfo(program, program_id, "glLinkProgram");
- ShaderTranslator* vertex_translator = NULL;
- ShaderTranslator* fragment_translator = NULL;
- if (use_shader_translator_) {
- vertex_translator = vertex_translator_.get();
- fragment_translator = fragment_translator_.get();
- }
if (program->Link(shader_manager(),
- vertex_translator,
- fragment_translator,
workarounds().count_all_in_varyings_packing ?
Program::kCountAll : Program::kCountOnlyStaticallyUsed,
shader_cache_callback_)) {
@@ -7096,24 +7088,17 @@ void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
if (!shader) {
return;
}
- ShaderTranslator* translator = NULL;
+
+ scoped_refptr<ShaderTranslatorInterface> translator;
if (use_shader_translator_) {
- translator = shader->shader_type() == GL_VERTEX_SHADER ?
- vertex_translator_.get() : fragment_translator_.get();
+ translator = shader->shader_type() == GL_VERTEX_SHADER ?
+ vertex_translator_ : fragment_translator_;
}
- shader->RequestCompile();
-
- // TODO(dyen): Currently we compile immediately when glCompileShader is
- // requested. Eventually this should be deffered to the linker stage.
- shader->DoCompile(
- translator,
- feature_info_->feature_flags().angle_translated_shader_source ?
- Shader::kANGLE : Shader::kGL);
-
- // CompileShader can be very slow. Exit command processing to allow for
- // context preemption and GPU watchdog checks.
- ExitCommandProcessingEarly();
+ const Shader::TranslatedShaderSourceType source_type =
+ feature_info_->feature_flags().angle_translated_shader_source ?
+ Shader::kANGLE : Shader::kGL;
+ shader->RequestCompile(translator, source_type);
}
void GLES2DecoderImpl::DoGetShaderiv(
@@ -7122,6 +7107,19 @@ void GLES2DecoderImpl::DoGetShaderiv(
if (!shader) {
return;
}
+
+ // Compile now for statuses that require it.
+ switch (pname) {
+ case GL_COMPILE_STATUS:
+ case GL_INFO_LOG_LENGTH:
+ case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+ shader->DoCompile();
+ break;
+
+ default:
+ break;
+ }
+
switch (pname) {
case GL_SHADER_SOURCE_LENGTH:
*params = shader->source().size();
@@ -7179,6 +7177,9 @@ error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
return error::kNoError;
}
+ // Make sure translator has been utilized in compile.
+ shader->DoCompile();
+
bucket->SetFromString(shader->translated_source().c_str());
return error::kNoError;
}
@@ -7214,6 +7215,10 @@ error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
bucket->SetFromString("");
return error::kNoError;
}
+
+ // Shader must be compiled in order to get the info log.
+ shader->DoCompile();
+
bucket->SetFromString(shader->log_info().c_str());
return error::kNoError;
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
index 381bb0c..80a0ce3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1.cc
@@ -248,7 +248,7 @@ void GLES2DecoderTestBase::SpecializedSetup<cmds::GetProgramInfoLog, 0>(
attach_cmd.Init(client_program_id_, kClientFragmentShaderId);
EXPECT_EQ(error::kNoError, ExecuteCmd(attach_cmd));
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
};
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
index 558f7b6..3f107c2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_programs.cc
@@ -1174,14 +1174,26 @@ TEST_P(GLES2DecoderWithShaderTest,
}
TEST_P(GLES2DecoderTest, CompileShaderValidArgs) {
+ // Compile shader should not actually call any GL calls yet.
+ CompileShader cmd;
+ cmd.Init(client_shader_id_);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+
+ // Getting the shader compilation state should trigger the actual GL calls.
EXPECT_CALL(*gl_, ShaderSource(kServiceShaderId, 1, _, _));
EXPECT_CALL(*gl_, CompileShader(kServiceShaderId));
EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_COMPILE_STATUS, _))
.WillOnce(SetArgPointee<2>(GL_TRUE))
.RetiresOnSaturation();
- CompileShader cmd;
- cmd.Init(client_shader_id_);
- EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_CALL(*gl_, GetError())
+ .WillOnce(Return(GL_NO_ERROR))
+ .WillOnce(Return(GL_NO_ERROR))
+ .RetiresOnSaturation();
+
+ GetShaderiv status_cmd;
+ status_cmd.Init(client_shader_id_, GL_COMPILE_STATUS,
+ kSharedMemoryId, kSharedMemoryOffset);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(status_cmd));
}
TEST_P(GLES2DecoderTest, CompileShaderInvalidArgs) {
diff --git a/gpu/command_buffer/service/memory_program_cache.cc b/gpu/command_buffer/service/memory_program_cache.cc
index 1e8e11b..16509e5 100644
--- a/gpu/command_buffer/service/memory_program_cache.cc
+++ b/gpu/command_buffer/service/memory_program_cache.cc
@@ -15,7 +15,6 @@
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/shader_manager.h"
-#include "gpu/command_buffer/service/shader_translator.h"
#include "ui/gl/gl_bindings.h"
namespace {
@@ -173,9 +172,7 @@ 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) {
char a_sha[kHashLength];
@@ -183,9 +180,9 @@ ProgramCache::ProgramLoadResult MemoryProgramCache::LoadLinkedProgram(
DCHECK(shader_a && !shader_a->last_compiled_source().empty() &&
shader_b && !shader_b->last_compiled_source().empty());
ComputeShaderHash(
- shader_a->last_compiled_source(), translator_a, a_sha);
+ shader_a->last_compiled_signature(), a_sha);
ComputeShaderHash(
- shader_b->last_compiled_source(), translator_b, b_sha);
+ shader_b->last_compiled_signature(), b_sha);
char sha[kHashLength];
ComputeProgramHash(a_sha,
@@ -235,9 +232,7 @@ 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;
@@ -259,9 +254,9 @@ void MemoryProgramCache::SaveLinkedProgram(
DCHECK(shader_a && !shader_a->last_compiled_source().empty() &&
shader_b && !shader_b->last_compiled_source().empty());
ComputeShaderHash(
- shader_a->last_compiled_source(), translator_a, a_sha);
+ shader_a->last_compiled_signature(), a_sha);
ComputeShaderHash(
- shader_b->last_compiled_source(), translator_b, b_sha);
+ shader_b->last_compiled_signature(), 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 7560d01..b5862d2 100644
--- a/gpu/command_buffer/service/memory_program_cache.h
+++ b/gpu/command_buffer/service/memory_program_cache.h
@@ -14,7 +14,6 @@
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/program_cache.h"
-#include "gpu/command_buffer/service/shader_translator.h"
namespace gpu {
namespace gles2 {
@@ -29,16 +28,12 @@ class GPU_EXPORT MemoryProgramCache : public ProgramCache {
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) override;
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 8f8c430..795b0af 100644
--- a/gpu/command_buffer/service/memory_program_cache_unittest.cc
+++ b/gpu/command_buffer/service/memory_program_cache_unittest.cc
@@ -190,16 +190,14 @@ TEST_F(MemoryProgramCacheTest, CacheSave) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
- vertex_shader_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
EXPECT_EQ(1, shader_cache_count());
}
@@ -215,16 +213,14 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
- vertex_shader_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
EXPECT_EQ(1, shader_cache_count());
@@ -232,10 +228,8 @@ TEST_F(MemoryProgramCacheTest, LoadProgram) {
cache_->LoadProgram(shader_cache_shader());
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
- vertex_shader_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
}
@@ -250,8 +244,8 @@ TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(1, shader_cache_count());
@@ -275,10 +269,8 @@ 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))));
@@ -305,8 +297,8 @@ TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(1, shader_cache_count());
@@ -333,10 +325,8 @@ 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))));
@@ -363,8 +353,8 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
@@ -372,10 +362,8 @@ 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))));
}
@@ -391,8 +379,8 @@ TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
@@ -402,10 +390,8 @@ 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))));
@@ -416,10 +402,8 @@ 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))));
}
@@ -439,9 +423,7 @@ 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)));
@@ -450,19 +432,15 @@ 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))));
}
@@ -479,8 +457,8 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
@@ -488,7 +466,7 @@ TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1;
// save old source and modify for new program
- const std::string& old_source = fragment_shader_->last_compiled_source();
+ const std::string& old_sig = fragment_shader_->last_compiled_signature();
fragment_shader_->set_source("al sdfkjdk");
TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
@@ -504,24 +482,18 @@ 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_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(
- old_source,
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ old_sig,
+ fragment_shader_->last_compiled_signature(),
NULL));
}
@@ -537,16 +509,14 @@ TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) {
vertex_shader_->set_source("different!");
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
- vertex_shader_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
}
@@ -561,16 +531,14 @@ TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
- vertex_shader_->last_compiled_source(),
- NULL,
- fragment_shader_->last_compiled_source(),
- NULL,
+ vertex_shader_->last_compiled_signature(),
+ fragment_shader_->last_compiled_signature(),
NULL));
SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
@@ -579,10 +547,8 @@ 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))));
}
@@ -598,8 +564,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) {
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
@@ -610,8 +576,8 @@ TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) {
}
ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2);
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2);
- cache_->SaveLinkedProgram(kProgramId, vertex_shader_, NULL,
- fragment_shader_, NULL, NULL,
+ cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
+ fragment_shader_, NULL,
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
base::Unretained(this)));
@@ -619,10 +585,8 @@ 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 87b3136..d5cff51 100644
--- a/gpu/command_buffer/service/mocks.h
+++ b/gpu/command_buffer/service/mocks.h
@@ -88,7 +88,6 @@ namespace gles2 {
class MockShaderTranslator : public ShaderTranslatorInterface {
public:
MockShaderTranslator();
- virtual ~MockShaderTranslator();
MOCK_METHOD5(Init, bool(
sh::GLenum shader_type,
@@ -106,6 +105,8 @@ class MockShaderTranslator : public ShaderTranslatorInterface {
NameMap* name_map));
MOCK_CONST_METHOD0(
GetStringForOptionsThatWouldAffectCompilation, std::string());
+ private:
+ ~MockShaderTranslator() override;
};
class MockProgramCache : public ProgramCache {
@@ -113,21 +114,17 @@ class MockProgramCache : public ProgramCache {
MockProgramCache();
virtual ~MockProgramCache();
- MOCK_METHOD7(LoadLinkedProgram, ProgramLoadResult(
+ MOCK_METHOD5(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_METHOD7(SaveLinkedProgram, void(
+ MOCK_METHOD5(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 abdcfc0..b219086 100644
--- a/gpu/command_buffer/service/program_cache.cc
+++ b/gpu/command_buffer/service/program_cache.cc
@@ -20,15 +20,13 @@ void ProgramCache::Clear() {
}
ProgramCache::LinkedProgramStatus ProgramCache::GetLinkedProgramStatus(
- const std::string& untranslated_a,
- const ShaderTranslatorInterface* translator_a,
- const std::string& untranslated_b,
- const ShaderTranslatorInterface* translator_b,
+ const std::string& shader_signature_a,
+ const std::string& shader_signature_b,
const std::map<std::string, GLint>* bind_attrib_location_map) const {
char a_sha[kHashLength];
char b_sha[kHashLength];
- ComputeShaderHash(untranslated_a, translator_a, a_sha);
- ComputeShaderHash(untranslated_b, translator_b, b_sha);
+ ComputeShaderHash(shader_signature_a, a_sha);
+ ComputeShaderHash(shader_signature_b, b_sha);
char sha[kHashLength];
ComputeProgramHash(a_sha,
@@ -46,15 +44,13 @@ 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 std::string& shader_signature_a,
+ const std::string& shader_signature_b,
const LocationMap* bind_attrib_location_map) {
char a_sha[kHashLength];
char b_sha[kHashLength];
- ComputeShaderHash(shader_a, translator_a, a_sha);
- ComputeShaderHash(shader_b, translator_b, b_sha);
+ ComputeShaderHash(shader_signature_a, a_sha);
+ ComputeShaderHash(shader_signature_b, b_sha);
char sha[kHashLength];
ComputeProgramHash(a_sha,
b_sha,
@@ -71,13 +67,9 @@ void ProgramCache::LinkedProgramCacheSuccess(const std::string& program_hash) {
void ProgramCache::ComputeShaderHash(
const std::string& str,
- const ShaderTranslatorInterface* translator,
char* result) const {
- std::string s((
- translator ? translator->GetStringForOptionsThatWouldAffectCompilation() :
- std::string()) + str);
- base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(s.c_str()),
- s.length(), reinterpret_cast<unsigned char*>(result));
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(str.c_str()),
+ str.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 3fb5687..624c436 100644
--- a/gpu/command_buffer/service/program_cache.h
+++ b/gpu/command_buffer/service/program_cache.h
@@ -18,7 +18,6 @@ namespace gpu {
namespace gles2 {
class Shader;
-class ShaderTranslator;
// Program cache base class for caching linked gpu programs
class GPU_EXPORT ProgramCache {
@@ -41,10 +40,8 @@ class GPU_EXPORT ProgramCache {
virtual ~ProgramCache();
LinkedProgramStatus GetLinkedProgramStatus(
- const std::string& untranslated_shader_a,
- const ShaderTranslatorInterface* translator_a,
- const std::string& untranslated_shader_b,
- const ShaderTranslatorInterface* translator_b,
+ const std::string& shader_signature_a,
+ const std::string& shader_signature_b,
const LocationMap* bind_attrib_location_map) const;
// Loads the linked program from the cache. If the program is not found or
@@ -52,9 +49,7 @@ 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) = 0;
@@ -63,9 +58,7 @@ 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;
@@ -75,10 +68,8 @@ class GPU_EXPORT ProgramCache {
void Clear();
// Only for testing
- void LinkedProgramCacheSuccess(const std::string& shader_a,
- const ShaderTranslatorInterface* translator_a,
- const std::string& shader_b,
- const ShaderTranslatorInterface* translator_b,
+ void LinkedProgramCacheSuccess(const std::string& shader_signature_a,
+ const std::string& shader_signature_b,
const LocationMap* bind_attrib_location_map);
protected:
@@ -87,7 +78,6 @@ 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 525fea1..7a4cbcd 100644
--- a/gpu/command_buffer/service/program_cache_unittest.cc
+++ b/gpu/command_buffer/service/program_cache_unittest.cc
@@ -18,18 +18,14 @@ class NoBackendProgramCache : public ProgramCache {
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 */) override {
return PROGRAM_LOAD_SUCCESS;
}
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 {}
@@ -38,14 +34,12 @@ class NoBackendProgramCache : public ProgramCache {
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, translator_1, a_sha);
- ComputeShaderHash(shader2, translator_2, b_sha);
+ ComputeShaderHash(shader1, a_sha);
+ ComputeShaderHash(shader2, b_sha);
char sha[kHashLength];
ComputeProgramHash(a_sha,
@@ -58,9 +52,8 @@ class NoBackendProgramCache : public ProgramCache {
}
void ComputeShaderHash(const std::string& shader,
- const ShaderTranslatorInterface* translator,
char* result) const {
- ProgramCache::ComputeShaderHash(shader, translator, result);
+ ProgramCache::ComputeShaderHash(shader, result);
}
void ComputeProgramHash(const char* hashed_shader_0,
@@ -95,8 +88,8 @@ TEST_F(ProgramCacheTest, LinkStatusSave) {
std::string shader_b = shader2;
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
cache_->GetLinkedProgramStatus(
- shader_a, NULL, shader_b, NULL, NULL));
- cache_->SaySuccessfullyCached(shader_a, NULL, shader_b, NULL, NULL);
+ shader_a, shader_b, NULL));
+ cache_->SaySuccessfullyCached(shader_a, shader_b, NULL);
shader_a.clear();
shader_b.clear();
@@ -104,37 +97,37 @@ TEST_F(ProgramCacheTest, LinkStatusSave) {
// make sure it was copied
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
cache_->GetLinkedProgramStatus(
- shader1, NULL, shader2, NULL, NULL));
+ shader1, shader2, NULL));
}
TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) {
const std::string shader1 = "abcd1234";
std::string shader2 = "abcda sda b1~#4 bbbbb1234";
- cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader2, NULL);
shader2 = "different!";
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, NULL));
}
TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) {
std::string shader1 = "abcd1234";
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
- cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader2, NULL);
shader1 = "different!";
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, NULL));
}
TEST_F(ProgramCacheTest, StatusEviction) {
const std::string shader1 = "abcd1234";
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
- cache_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader2, NULL);
char a_sha[ProgramCache::kHashLength];
char b_sha[ProgramCache::kHashLength];
- cache_->ComputeShaderHash(shader1, NULL, a_sha);
- cache_->ComputeShaderHash(shader2, NULL, b_sha);
+ cache_->ComputeShaderHash(shader1, a_sha);
+ cache_->ComputeShaderHash(shader2, b_sha);
char sha[ProgramCache::kHashLength];
cache_->ComputeProgramHash(a_sha,
@@ -143,22 +136,22 @@ TEST_F(ProgramCacheTest, StatusEviction) {
sha);
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, 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_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
- cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader2, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader3, NULL);
char a_sha[ProgramCache::kHashLength];
char b_sha[ProgramCache::kHashLength];
char c_sha[ProgramCache::kHashLength];
- cache_->ComputeShaderHash(shader1, NULL, a_sha);
- cache_->ComputeShaderHash(shader2, NULL, b_sha);
- cache_->ComputeShaderHash(shader3, NULL, c_sha);
+ cache_->ComputeShaderHash(shader1, a_sha);
+ cache_->ComputeShaderHash(shader2, b_sha);
+ cache_->ComputeShaderHash(shader3, c_sha);
char sha[ProgramCache::kHashLength];
cache_->ComputeProgramHash(a_sha,
@@ -167,9 +160,9 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) {
sha);
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, NULL));
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader3, NULL));
cache_->ComputeProgramHash(a_sha,
@@ -178,22 +171,22 @@ TEST_F(ProgramCacheTest, EvictionWithReusedShader) {
sha);
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, NULL));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader3, 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_->SaySuccessfullyCached(shader1, NULL, shader2, NULL, NULL);
- cache_->SaySuccessfullyCached(shader1, NULL, shader3, NULL, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader2, NULL);
+ cache_->SaySuccessfullyCached(shader1, shader3, NULL);
cache_->Clear();
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader2, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader2, NULL));
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
- cache_->GetLinkedProgramStatus(shader1, NULL, shader3, NULL, NULL));
+ cache_->GetLinkedProgramStatus(shader1, shader3, NULL));
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index cbdf919..51b0d6e 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -24,7 +24,6 @@
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/program_cache.h"
#include "gpu/command_buffer/service/shader_manager.h"
-#include "gpu/command_buffer/service/shader_translator.h"
#include "third_party/re2/re2/re2.h"
using base::TimeDelta;
@@ -515,48 +514,14 @@ void Program::ExecuteBindAttribLocationCalls() {
}
bool Program::Link(ShaderManager* manager,
- ShaderTranslator* vertex_translator,
- ShaderTranslator* fragment_translator,
Program::VaryingsPackingOption varyings_packing_option,
const ShaderCacheCallback& shader_callback) {
ClearLinkStatus();
- if (!CanLink()) {
+
+ if (!AttachedShadersExist()) {
set_log_info("missing shaders");
return false;
}
- if (DetectAttribLocationBindingConflicts()) {
- set_log_info("glBindAttribLocation() conflicts");
- return false;
- }
- std::string conflicting_name;
- if (DetectUniformsMismatch(&conflicting_name)) {
- std::string info_log = "Uniforms with the same name but different "
- "type/precision: " + conflicting_name;
- set_log_info(ProcessLogInfo(info_log).c_str());
- return false;
- }
- if (DetectVaryingsMismatch(&conflicting_name)) {
- std::string info_log = "Varyings with the same name but different type, "
- "or statically used varyings in fragment shader are "
- "not declared in vertex shader: " + conflicting_name;
- set_log_info(ProcessLogInfo(info_log).c_str());
- return false;
- }
- if (DetectBuiltInInvariantConflicts()) {
- set_log_info("Invariant settings for certain built-in varyings "
- "have to match");
- return false;
- }
- if (DetectGlobalNameConflicts(&conflicting_name)) {
- std::string info_log = "Name conflicts between an uniform and an "
- "attribute: " + conflicting_name;
- set_log_info(ProcessLogInfo(info_log).c_str());
- return false;
- }
- if (!CheckVaryingsPacking(varyings_packing_option)) {
- set_log_info("Varyings over maximum register limit");
- return false;
- }
TimeTicks before_time = TimeTicks::Now();
bool link = true;
@@ -565,19 +530,15 @@ bool Program::Link(ShaderManager* manager,
DCHECK(!attached_shaders_[0]->last_compiled_source().empty() &&
!attached_shaders_[1]->last_compiled_source().empty());
ProgramCache::LinkedProgramStatus status = cache->GetLinkedProgramStatus(
- attached_shaders_[0]->last_compiled_source(),
- vertex_translator,
- attached_shaders_[1]->last_compiled_source(),
- fragment_translator,
+ attached_shaders_[0]->last_compiled_signature(),
+ attached_shaders_[1]->last_compiled_signature(),
&bind_attrib_location_map_);
if (status == ProgramCache::LINK_SUCCEEDED) {
ProgramCache::ProgramLoadResult success =
cache->LoadLinkedProgram(service_id(),
attached_shaders_[0].get(),
- vertex_translator,
attached_shaders_[1].get(),
- fragment_translator,
&bind_attrib_location_map_,
shader_callback);
link = success != ProgramCache::PROGRAM_LOAD_SUCCESS;
@@ -586,6 +547,47 @@ bool Program::Link(ShaderManager* manager,
}
if (link) {
+ CompileAttachedShaders();
+
+ if (!CanLink()) {
+ set_log_info("invalid shaders");
+ return false;
+ }
+ if (DetectAttribLocationBindingConflicts()) {
+ set_log_info("glBindAttribLocation() conflicts");
+ return false;
+ }
+ std::string conflicting_name;
+ if (DetectUniformsMismatch(&conflicting_name)) {
+ std::string info_log = "Uniforms with the same name but different "
+ "type/precision: " + conflicting_name;
+ set_log_info(ProcessLogInfo(info_log).c_str());
+ return false;
+ }
+ if (DetectVaryingsMismatch(&conflicting_name)) {
+ std::string info_log = "Varyings with the same name but different type, "
+ "or statically used varyings in fragment shader "
+ "are not declared in vertex shader: " +
+ conflicting_name;
+ set_log_info(ProcessLogInfo(info_log).c_str());
+ return false;
+ }
+ if (DetectBuiltInInvariantConflicts()) {
+ set_log_info("Invariant settings for certain built-in varyings "
+ "have to match");
+ return false;
+ }
+ if (DetectGlobalNameConflicts(&conflicting_name)) {
+ std::string info_log = "Name conflicts between an uniform and an "
+ "attribute: " + conflicting_name;
+ set_log_info(ProcessLogInfo(info_log).c_str());
+ return false;
+ }
+ if (!CheckVaryingsPacking(varyings_packing_option)) {
+ set_log_info("Varyings over maximum register limit");
+ return false;
+ }
+
ExecuteBindAttribLocationCalls();
before_time = TimeTicks::Now();
if (cache && gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
@@ -604,9 +606,7 @@ bool Program::Link(ShaderManager* manager,
if (cache) {
cache->SaveLinkedProgram(service_id(),
attached_shaders_[0].get(),
- vertex_translator,
attached_shaders_[1].get(),
- fragment_translator,
&bind_attrib_location_map_,
shader_callback);
}
@@ -1001,6 +1001,23 @@ void Program::DetachShaders(ShaderManager* shader_manager) {
}
}
+void Program::CompileAttachedShaders() {
+ for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
+ Shader* shader = attached_shaders_[ii].get();
+ if (shader) {
+ shader->DoCompile();
+ }
+ }
+}
+
+bool Program::AttachedShadersExist() const {
+ for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
+ if (!attached_shaders_[ii].get())
+ return false;
+ }
+ return true;
+}
+
bool Program::CanLink() const {
for (int ii = 0; ii < kMaxAttachedShaders; ++ii) {
if (!attached_shaders_[ii].get() || !attached_shaders_[ii]->valid()) {
diff --git a/gpu/command_buffer/service/program_manager.h b/gpu/command_buffer/service/program_manager.h
index be5fb2f..e6b2d77 100644
--- a/gpu/command_buffer/service/program_manager.h
+++ b/gpu/command_buffer/service/program_manager.h
@@ -24,7 +24,6 @@ class ProgramCache;
class ProgramManager;
class Shader;
class ShaderManager;
-class ShaderTranslator;
// This is used to track which attributes a particular program needs
// so we can verify at glDrawXXX time that every attribute is either disabled
@@ -179,12 +178,12 @@ class GPU_EXPORT Program : public base::RefCounted<Program> {
bool AttachShader(ShaderManager* manager, Shader* shader);
bool DetachShader(ShaderManager* manager, Shader* shader);
+ void CompileAttachedShaders();
+ bool AttachedShadersExist() const;
bool CanLink() const;
// Performs glLinkProgram and related activities.
bool Link(ShaderManager* manager,
- ShaderTranslator* vertex_translator,
- ShaderTranslator* fragment_shader,
VaryingsPackingOption varyings_packing_option,
const ShaderCacheCallback& shader_callback);
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc
index 0584cee..33da572 100644
--- a/gpu/command_buffer/service/program_manager_unittest.cc
+++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -242,7 +242,7 @@ class ProgramManagerWithShaderTest : public GpuServiceTest {
program_->AttachShader(&shader_manager_, vertex_shader);
program_->AttachShader(&shader_manager_, fragment_shader);
- program_->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
}
@@ -272,7 +272,7 @@ class ProgramManagerWithShaderTest : public GpuServiceTest {
SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
service_id);
}
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
GLint link_status;
program->GetProgramiv(GL_LINK_STATUS, &link_status);
@@ -715,7 +715,7 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
ASSERT_TRUE(program != NULL);
EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
GLint value = 0;
program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
@@ -784,7 +784,7 @@ TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
ASSERT_TRUE(program != NULL);
EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
// Check that we get the correct locations.
@@ -880,7 +880,7 @@ TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
ASSERT_TRUE(program!= NULL);
EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
// Check that we got the good type, not the bad.
// Check Attribs
@@ -1728,7 +1728,7 @@ TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
const size_t kNumUniforms = arraysize(kUniforms);
SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
kServiceProgramId);
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
manager_.ClearUniforms(program);
@@ -1801,7 +1801,7 @@ TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
const size_t kNumUniforms = arraysize(kUniforms);
SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
kServiceProgramId);
- program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
+ program->Link(NULL, Program::kCountOnlyStaticallyUsed,
base::Bind(&ShaderCacheCb));
EXPECT_EQ(kUniform1DesiredLocation,
@@ -1862,9 +1862,7 @@ class ProgramManagerWithCacheTest : public GpuServiceTest {
void SetProgramCached() {
cache_->LinkedProgramCacheSuccess(
vertex_shader_->source(),
- NULL,
fragment_shader_->source(),
- NULL,
&program_->bind_attrib_location_map());
}
@@ -1881,9 +1879,7 @@ class ProgramManagerWithCacheTest : public GpuServiceTest {
EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
program->service_id(),
vertex_shader,
- NULL,
fragment_shader,
- NULL,
&program->bind_attrib_location_map(),
_)).Times(1);
}
@@ -1901,9 +1897,7 @@ class ProgramManagerWithCacheTest : public GpuServiceTest {
EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
program->service_id(),
vertex_shader,
- NULL,
fragment_shader,
- NULL,
&program->bind_attrib_location_map(),
_)).Times(0);
}
@@ -1925,9 +1919,7 @@ class ProgramManagerWithCacheTest : public GpuServiceTest {
EXPECT_CALL(*cache_.get(),
LoadLinkedProgram(service_program_id,
vertex_shader,
- NULL,
fragment_shader,
- NULL,
&program->bind_attrib_location_map(),
_))
.WillOnce(Return(result));
@@ -2018,8 +2010,8 @@ TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
SetShadersCompiled();
SetExpectationsForProgramLink();
SetExpectationsForProgramCached();
- EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
- Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
+ EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
+ base::Bind(&ShaderCacheCb)));
}
TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
@@ -2032,8 +2024,8 @@ TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
SetExpectationsForNotCachingProgram();
SetExpectationsForProgramLoadSuccess();
- EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
- Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
+ EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
+ base::Bind(&ShaderCacheCb)));
}
} // namespace gles2
diff --git a/gpu/command_buffer/service/shader_manager.cc b/gpu/command_buffer/service/shader_manager.cc
index 90b1576..6860041 100644
--- a/gpu/command_buffer/service/shader_manager.cc
+++ b/gpu/command_buffer/service/shader_manager.cc
@@ -29,19 +29,22 @@ Shader::Shader(GLuint service_id, GLenum shader_type)
shader_state_(kShaderStateWaiting),
service_id_(service_id),
shader_type_(shader_type),
+ source_type_(kANGLE),
valid_(false) {
}
Shader::~Shader() {
}
-void Shader::RequestCompile() {
+void Shader::RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator,
+ TranslatedShaderSourceType type) {
shader_state_ = kShaderStateCompileRequested;
+ translator_ = translator;
+ source_type_ = type;
last_compiled_source_ = source_;
}
-void Shader::DoCompile(ShaderTranslatorInterface* translator,
- TranslatedShaderSourceType type) {
+void Shader::DoCompile() {
// We require that RequestCompile() must be called before DoCompile(),
// so we can return early if the shader state is not what we expect.
if (shader_state_ != kShaderStateCompileRequested) {
@@ -55,6 +58,7 @@ void Shader::DoCompile(ShaderTranslatorInterface* translator,
// Translate GL ES 2.0 shader to Desktop GL shader and pass that to
// glShaderSource and then glCompileShader.
const char* source_for_driver = last_compiled_source_.c_str();
+ ShaderTranslatorInterface* translator = translator_.get();
if (translator) {
valid_ = translator->Translate(last_compiled_source_,
&log_info_,
@@ -71,7 +75,7 @@ void Shader::DoCompile(ShaderTranslatorInterface* translator,
glShaderSource(service_id_, 1, &source_for_driver, NULL);
glCompileShader(service_id_);
- if (type == kANGLE) {
+ if (source_type_ == kANGLE) {
GLint max_len = 0;
glGetShaderiv(service_id_,
GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE,
diff --git a/gpu/command_buffer/service/shader_manager.h b/gpu/command_buffer/service/shader_manager.h
index 11f567d..82fd288 100644
--- a/gpu/command_buffer/service/shader_manager.h
+++ b/gpu/command_buffer/service/shader_manager.h
@@ -35,10 +35,10 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> {
kShaderStateCompiled, // Signifies compile happened, not valid compile.
};
- void RequestCompile();
+ void RequestCompile(scoped_refptr<ShaderTranslatorInterface> translator,
+ TranslatedShaderSourceType type);
- void DoCompile(ShaderTranslatorInterface* translator,
- TranslatedShaderSourceType type);
+ void DoCompile();
ShaderState shader_state() const {
return shader_state_;
@@ -64,7 +64,15 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> {
return translated_source_;
}
- const std::string& last_compiled_source() const {
+ std::string last_compiled_source() const {
+ return last_compiled_source_;
+ }
+
+ std::string last_compiled_signature() const {
+ if (translator_.get()) {
+ return last_compiled_source_ +
+ translator_->GetStringForOptionsThatWouldAffectCompilation();
+ }
return last_compiled_source_;
}
@@ -152,6 +160,12 @@ class GPU_EXPORT Shader : public base::RefCounted<Shader> {
// Type of shader - GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
GLenum shader_type_;
+ // Translated source type when shader was last requested to be compiled.
+ TranslatedShaderSourceType source_type_;
+
+ // Translator to use, set when shader was last requested to be compiled.
+ scoped_refptr<ShaderTranslatorInterface> translator_;
+
// True if compilation succeeded.
bool valid_;
diff --git a/gpu/command_buffer/service/shader_manager_unittest.cc b/gpu/command_buffer/service/shader_manager_unittest.cc
index f5f6206..c46b734 100644
--- a/gpu/command_buffer/service/shader_manager_unittest.cc
+++ b/gpu/command_buffer/service/shader_manager_unittest.cc
@@ -140,14 +140,14 @@ TEST_F(ShaderManagerTest, DoCompile) {
EXPECT_TRUE(shader1->last_compiled_source().empty());
// Check that DoCompile() will not work if RequestCompile() was not called.
- MockShaderTranslator translator;
- shader1->DoCompile(&translator, Shader::kANGLE);
+ shader1->DoCompile();
EXPECT_EQ(Shader::kShaderStateWaiting, shader1->shader_state());
EXPECT_FALSE(shader1->valid());
// Check RequestCompile() will update the state and last compiled source, but
// still keep the actual compile state invalid.
- shader1->RequestCompile();
+ scoped_refptr<ShaderTranslatorInterface> translator(new MockShaderTranslator);
+ shader1->RequestCompile(translator, Shader::kANGLE);
EXPECT_EQ(Shader::kShaderStateCompileRequested, shader1->shader_state());
EXPECT_STREQ(kClient1Source, shader1->last_compiled_source().c_str());
EXPECT_FALSE(shader1->valid());
diff --git a/gpu/command_buffer/service/shader_translator.h b/gpu/command_buffer/service/shader_translator.h
index ef25ebb..818be5d 100644
--- a/gpu/command_buffer/service/shader_translator.h
+++ b/gpu/command_buffer/service/shader_translator.h
@@ -27,8 +27,10 @@ typedef base::hash_map<std::string, std::string> NameMap;
// Translates a GLSL ES 2.0 shader to desktop GLSL shader, or just
// validates GLSL ES 2.0 shaders on a true GLSL ES implementation.
-class ShaderTranslatorInterface {
+class ShaderTranslatorInterface
+ : public base::RefCounted<ShaderTranslatorInterface> {
public:
+ ShaderTranslatorInterface() {}
enum GlslImplementationType {
kGlsl,
kGlslES
@@ -62,12 +64,15 @@ class ShaderTranslatorInterface {
protected:
virtual ~ShaderTranslatorInterface() {}
+
+ private:
+ friend class base::RefCounted<ShaderTranslatorInterface>;
+ DISALLOW_COPY_AND_ASSIGN(ShaderTranslatorInterface);
};
// Implementation of ShaderTranslatorInterface
class GPU_EXPORT ShaderTranslator
- : public base::RefCounted<ShaderTranslator>,
- NON_EXPORTED_BASE(public ShaderTranslatorInterface) {
+ : NON_EXPORTED_BASE(public ShaderTranslatorInterface) {
public:
class DestructionObserver {
public:
@@ -104,17 +109,14 @@ class GPU_EXPORT ShaderTranslator
void RemoveDestructionObserver(DestructionObserver* observer);
private:
- friend class base::RefCounted<ShaderTranslator>;
-
~ShaderTranslator() override;
+
int GetCompileOptions() const;
ShHandle compiler_;
bool implementation_is_glsl_es_;
ShCompileOptions driver_bug_workarounds_;
ObserverList<DestructionObserver> destruction_observers_;
-
- DISALLOW_COPY_AND_ASSIGN(ShaderTranslator);
};
} // namespace gles2
diff --git a/gpu/command_buffer/service/test_helper.cc b/gpu/command_buffer/service/test_helper.cc
index 6cd0acf..096a60c 100644
--- a/gpu/command_buffer/service/test_helper.cc
+++ b/gpu/command_buffer/service/test_helper.cc
@@ -761,14 +761,15 @@ void TestHelper::SetShaderStates(
const NameMap* name_map = (expected_name_map && expected_valid) ?
expected_name_map : &empty_name_map;
- MockShaderTranslator translator;
- EXPECT_CALL(translator, Translate(_,
- NotNull(), // log_info
- NotNull(), // translated_source
- NotNull(), // attrib_map
- NotNull(), // uniform_map
- NotNull(), // varying_map
- NotNull())) // name_map
+ MockShaderTranslator* mock_translator = new MockShaderTranslator;
+ scoped_refptr<ShaderTranslatorInterface> translator(mock_translator);
+ EXPECT_CALL(*mock_translator, Translate(_,
+ NotNull(), // log_info
+ NotNull(), // translated_source
+ NotNull(), // attrib_map
+ NotNull(), // uniform_map
+ NotNull(), // varying_map
+ NotNull())) // name_map
.WillOnce(DoAll(SetArgumentPointee<1>(*log_info),
SetArgumentPointee<2>(*translated_source),
SetArgumentPointee<3>(*attrib_map),
@@ -790,8 +791,8 @@ void TestHelper::SetShaderStates(
.WillOnce(SetArgumentPointee<2>(GL_TRUE))
.RetiresOnSaturation();
}
- shader->RequestCompile();
- shader->DoCompile(&translator, Shader::kGL);
+ shader->RequestCompile(translator, Shader::kGL);
+ shader->DoCompile();
}
// static
diff --git a/gpu/command_buffer/tests/gl_program_unittest.cc b/gpu/command_buffer/tests/gl_program_unittest.cc
index 186b28b..d243994 100644
--- a/gpu/command_buffer/tests/gl_program_unittest.cc
+++ b/gpu/command_buffer/tests/gl_program_unittest.cc
@@ -4,7 +4,9 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#include <GLES2/gl2extchromium.h>
+#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/tests/gl_manager.h"
#include "gpu/command_buffer/tests/gl_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -187,5 +189,67 @@ TEST_F(GLProgramTest, UniformsInCurrentProgram) {
GLTestHelper::CheckGLError("no errors", __LINE__);
}
+TEST_F(GLProgramTest, DeferCompileWithExt) {
+ // This test must have extensions enabled.
+ gles2::ContextGroup* context_group = gl_.decoder()->GetContextGroup();
+ gles2::FeatureInfo* feature_info = context_group->feature_info();
+ const gles2::FeatureInfo::FeatureFlags& flags = feature_info->feature_flags();
+ if (!flags.ext_frag_depth)
+ return;
+
+ static const char* v_shdr_str = R"(
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+ )";
+ static const char* f_shdr_str = R"(
+ #extension GL_EXT_frag_depth : enable
+ void main()
+ {
+ gl_FragDepthEXT = 1.0;
+ }
+ )";
+
+ // First compile and link to be shader compiles.
+ GLuint vs_good = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
+ GLuint fs_good = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
+ GLuint program_good = GLTestHelper::LinkProgram(vs_good, fs_good);
+ GLint linked_good = 0;
+ glGetProgramiv(program_good, GL_LINK_STATUS, &linked_good);
+ EXPECT_NE(0, linked_good);
+
+ // Disable extension and be sure shader no longer compiles.
+ ASSERT_TRUE(glEnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"));
+ GLuint vs_bad = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
+ GLuint fs_bad = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
+ GLuint program_bad = GLTestHelper::LinkProgram(vs_bad, fs_bad);
+ GLint linked_bad = 0;
+ glGetProgramiv(program_bad, GL_LINK_STATUS, &linked_bad);
+ EXPECT_EQ(0, linked_bad);
+
+ // Relinking good compilations without extension disabled should still link.
+ GLuint program_defer_good = GLTestHelper::LinkProgram(vs_good, fs_good);
+ GLint linked_defer_good = 0;
+ glGetProgramiv(program_defer_good, GL_LINK_STATUS, &linked_defer_good);
+ EXPECT_NE(0, linked_defer_good);
+
+ // linking bad compilations with extension enabled should still not link.
+ GLuint vs_bad2 = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
+ GLuint fs_bad2 = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
+ glRequestExtensionCHROMIUM("GL_EXT_frag_depth");
+ GLuint program_bad2 = GLTestHelper::LinkProgram(vs_bad2, fs_bad2);
+ GLint linked_bad2 = 0;
+ glGetProgramiv(program_bad2, GL_LINK_STATUS, &linked_bad2);
+ EXPECT_EQ(0, linked_bad2);
+
+ // Be sure extension was actually turned on by recompiling.
+ GLuint vs_good2 = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shdr_str);
+ GLuint fs_good2 = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_shdr_str);
+ GLuint program_good2 = GLTestHelper::SetupProgram(vs_good2, fs_good2);
+ EXPECT_NE(0u, program_good2);
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_test_utils.cc b/gpu/command_buffer/tests/gl_test_utils.cc
index d3272ca..7582a5d 100644
--- a/gpu/command_buffer/tests/gl_test_utils.cc
+++ b/gpu/command_buffer/tests/gl_test_utils.cc
@@ -31,12 +31,19 @@ bool GLTestHelper::CheckGLError(const char* msg, int line) {
return success;
}
-GLuint GLTestHelper::LoadShader(GLenum type, const char* shaderSrc) {
+GLuint GLTestHelper::CompileShader(GLenum type, const char* shaderSrc) {
GLuint shader = glCreateShader(type);
// Load the shader source
glShaderSource(shader, 1, &shaderSrc, NULL);
// Compile the shader
glCompileShader(shader);
+
+ return shader;
+}
+
+GLuint GLTestHelper::LoadShader(GLenum type, const char* shaderSrc) {
+ GLuint shader = CompileShader(type, shaderSrc);
+
// Check the compile status
GLint value = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
@@ -52,7 +59,7 @@ GLuint GLTestHelper::LoadShader(GLenum type, const char* shaderSrc) {
return shader;
}
-GLuint GLTestHelper::SetupProgram(
+GLuint GLTestHelper::LinkProgram(
GLuint vertex_shader, GLuint fragment_shader) {
// Create the program object
GLuint program = glCreateProgram();
@@ -60,6 +67,13 @@ GLuint GLTestHelper::SetupProgram(
glAttachShader(program, fragment_shader);
// Link the program
glLinkProgram(program);
+
+ return program;
+}
+
+GLuint GLTestHelper::SetupProgram(
+ GLuint vertex_shader, GLuint fragment_shader) {
+ GLuint program = LinkProgram(vertex_shader, fragment_shader);
// Check the link status
GLint linked = 0;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
diff --git a/gpu/command_buffer/tests/gl_test_utils.h b/gpu/command_buffer/tests/gl_test_utils.h
index 15a726e..802d54d 100644
--- a/gpu/command_buffer/tests/gl_test_utils.h
+++ b/gpu/command_buffer/tests/gl_test_utils.h
@@ -18,11 +18,19 @@ class GLTestHelper {
static bool CheckGLError(const char* msg, int line);
// Compiles a shader.
- // Returns shader, 0 on failure..
+ // Does not check for errors, always returns shader.
+ static GLuint CompileShader(GLenum type, const char* shaderSrc);
+
+ // Compiles a shader and checks for compilation errors.
+ // Returns shader, 0 on failure.
static GLuint LoadShader(GLenum type, const char* shaderSrc);
// Attaches 2 shaders and links them to a program.
- // Returns program, 0 on failure..
+ // Does not check for errors, always returns program.
+ static GLuint LinkProgram(GLuint vertex_shader, GLuint fragment_shader);
+
+ // Attaches 2 shaders, links them to a program, and checks for errors.
+ // Returns program, 0 on failure.
static GLuint SetupProgram(GLuint vertex_shader, GLuint fragment_shader);
// Compiles 2 shaders, attaches and links them to a program