| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "gpu/command_buffer/service/program_manager.h" | 5 #include "gpu/command_buffer/service/program_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "gpu/command_buffer/common/gl_mock.h" | 12 #include "gpu/command_buffer/common/gl_mock.h" |
| 13 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 13 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
| 14 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 15 #include "gpu/command_buffer/service/common_decoder.h" | 15 #include "gpu/command_buffer/service/common_decoder.h" |
| 16 #include "gpu/command_buffer/service/feature_info.h" | |
| 17 #include "gpu/command_buffer/service/mocks.h" | 16 #include "gpu/command_buffer/service/mocks.h" |
| 18 #include "gpu/command_buffer/service/test_helper.h" | 17 #include "gpu/command_buffer/service/test_helper.h" |
| 19 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 20 | 19 |
| 21 using ::gfx::MockGLInterface; | 20 using ::gfx::MockGLInterface; |
| 22 using ::testing::_; | 21 using ::testing::_; |
| 23 using ::testing::DoAll; | 22 using ::testing::DoAll; |
| 24 using ::testing::InSequence; | 23 using ::testing::InSequence; |
| 25 using ::testing::MatcherCast; | 24 using ::testing::MatcherCast; |
| 26 using ::testing::Pointee; | 25 using ::testing::Pointee; |
| 27 using ::testing::Return; | 26 using ::testing::Return; |
| 28 using ::testing::ReturnRef; | 27 using ::testing::ReturnRef; |
| 29 using ::testing::SetArrayArgument; | 28 using ::testing::SetArrayArgument; |
| 30 using ::testing::SetArgumentPointee; | 29 using ::testing::SetArgumentPointee; |
| 31 using ::testing::StrEq; | 30 using ::testing::StrEq; |
| 32 using ::testing::StrictMock; | 31 using ::testing::StrictMock; |
| 33 | 32 |
| 34 namespace gpu { | 33 namespace gpu { |
| 35 namespace gles2 { | 34 namespace gles2 { |
| 36 | 35 |
| 37 class ProgramManagerTest : public testing::Test { | 36 class ProgramManagerTest : public testing::Test { |
| 38 public: | 37 public: |
| 39 ProgramManagerTest() : manager_(NULL) { } | 38 ProgramManagerTest() { } |
| 40 ~ProgramManagerTest() { | 39 ~ProgramManagerTest() { |
| 41 manager_.Destroy(false); | 40 manager_.Destroy(false); |
| 42 } | 41 } |
| 43 | 42 |
| 44 protected: | 43 protected: |
| 45 virtual void SetUp() { | 44 virtual void SetUp() { |
| 46 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); | 45 gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); |
| 47 ::gfx::GLInterface::SetGLInterface(gl_.get()); | 46 ::gfx::GLInterface::SetGLInterface(gl_.get()); |
| 48 } | 47 } |
| 49 | 48 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 EXPECT_FALSE(info1->InUse()); | 127 EXPECT_FALSE(info1->InUse()); |
| 129 EXPECT_FALSE(info1->IsValid()); | 128 EXPECT_FALSE(info1->IsValid()); |
| 130 EXPECT_FALSE(info1->IsDeleted()); | 129 EXPECT_FALSE(info1->IsDeleted()); |
| 131 EXPECT_FALSE(info1->CanLink()); | 130 EXPECT_FALSE(info1->CanLink()); |
| 132 EXPECT_TRUE(info1->log_info() == NULL); | 131 EXPECT_TRUE(info1->log_info() == NULL); |
| 133 } | 132 } |
| 134 | 133 |
| 135 class ProgramManagerWithShaderTest : public testing::Test { | 134 class ProgramManagerWithShaderTest : public testing::Test { |
| 136 public: | 135 public: |
| 137 ProgramManagerWithShaderTest() | 136 ProgramManagerWithShaderTest() |
| 138 : manager_(NULL), program_info_(NULL) { | 137 : program_info_(NULL) { |
| 139 } | 138 } |
| 140 | 139 |
| 141 ~ProgramManagerWithShaderTest() { | 140 ~ProgramManagerWithShaderTest() { |
| 142 manager_.Destroy(false); | 141 manager_.Destroy(false); |
| 143 shader_manager_.Destroy(false); | 142 shader_manager_.Destroy(false); |
| 144 } | 143 } |
| 145 | 144 |
| 146 static const GLint kNumVertexAttribs = 16; | 145 static const GLint kNumVertexAttribs = 16; |
| 147 | 146 |
| 148 static const GLuint kClientProgramId = 123; | 147 static const GLuint kClientProgramId = 123; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 ASSERT_TRUE(fragment_shader != NULL); | 211 ASSERT_TRUE(fragment_shader != NULL); |
| 213 vertex_shader->SetStatus(true, NULL, NULL); | 212 vertex_shader->SetStatus(true, NULL, NULL); |
| 214 fragment_shader->SetStatus(true, NULL, NULL); | 213 fragment_shader->SetStatus(true, NULL, NULL); |
| 215 | 214 |
| 216 program_info_ = manager_.CreateProgramInfo( | 215 program_info_ = manager_.CreateProgramInfo( |
| 217 kClientProgramId, kServiceProgramId); | 216 kClientProgramId, kServiceProgramId); |
| 218 ASSERT_TRUE(program_info_ != NULL); | 217 ASSERT_TRUE(program_info_ != NULL); |
| 219 | 218 |
| 220 program_info_->AttachShader(&shader_manager_, vertex_shader); | 219 program_info_->AttachShader(&shader_manager_, vertex_shader); |
| 221 program_info_->AttachShader(&shader_manager_, fragment_shader); | 220 program_info_->AttachShader(&shader_manager_, fragment_shader); |
| 222 program_info_->Link(NULL, NULL, NULL, NULL); | 221 program_info_->Link(); |
| 223 } | 222 } |
| 224 | 223 |
| 225 void SetupShader(AttribInfo* attribs, size_t num_attribs, | 224 void SetupShader(AttribInfo* attribs, size_t num_attribs, |
| 226 UniformInfo* uniforms, size_t num_uniforms, | 225 UniformInfo* uniforms, size_t num_uniforms, |
| 227 GLuint service_id) { | 226 GLuint service_id) { |
| 228 TestHelper::SetupShader( | 227 TestHelper::SetupShader( |
| 229 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id); | 228 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id); |
| 230 } | 229 } |
| 231 | 230 |
| 232 void SetupDefaultShaderExpectations() { | 231 void SetupDefaultShaderExpectations() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 245 } | 244 } |
| 246 | 245 |
| 247 // Return true if link status matches expected_link_status | 246 // Return true if link status matches expected_link_status |
| 248 bool LinkAsExpected(ProgramManager::ProgramInfo* program_info, | 247 bool LinkAsExpected(ProgramManager::ProgramInfo* program_info, |
| 249 bool expected_link_status) { | 248 bool expected_link_status) { |
| 250 GLuint service_id = program_info->service_id(); | 249 GLuint service_id = program_info->service_id(); |
| 251 if (expected_link_status) { | 250 if (expected_link_status) { |
| 252 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, | 251 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, |
| 253 service_id); | 252 service_id); |
| 254 } | 253 } |
| 255 program_info->Link(NULL, NULL, NULL, NULL); | 254 program_info->Link(); |
| 256 GLint link_status; | 255 GLint link_status; |
| 257 program_info->GetProgramiv(GL_LINK_STATUS, &link_status); | 256 program_info->GetProgramiv(GL_LINK_STATUS, &link_status); |
| 258 return (static_cast<bool>(link_status) == expected_link_status); | 257 return (static_cast<bool>(link_status) == expected_link_status); |
| 259 } | 258 } |
| 260 | 259 |
| 261 static AttribInfo kAttribs[]; | 260 static AttribInfo kAttribs[]; |
| 262 static UniformInfo kUniforms[]; | 261 static UniformInfo kUniforms[]; |
| 263 | 262 |
| 264 scoped_ptr<StrictMock<gfx::MockGLInterface> > gl_; | 263 scoped_ptr<StrictMock<gfx::MockGLInterface> > gl_; |
| 265 | 264 |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 vshader->SetStatus(true, "", NULL); | 577 vshader->SetStatus(true, "", NULL); |
| 579 ShaderManager::ShaderInfo* fshader = shader_manager_.CreateShaderInfo( | 578 ShaderManager::ShaderInfo* fshader = shader_manager_.CreateShaderInfo( |
| 580 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER); | 579 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER); |
| 581 ASSERT_TRUE(fshader != NULL); | 580 ASSERT_TRUE(fshader != NULL); |
| 582 fshader->SetStatus(true, "", NULL); | 581 fshader->SetStatus(true, "", NULL); |
| 583 ProgramManager::ProgramInfo* program_info = | 582 ProgramManager::ProgramInfo* program_info = |
| 584 manager_.CreateProgramInfo(kClientProgramId, kServiceProgramId); | 583 manager_.CreateProgramInfo(kClientProgramId, kServiceProgramId); |
| 585 ASSERT_TRUE(program_info != NULL); | 584 ASSERT_TRUE(program_info != NULL); |
| 586 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, vshader)); | 585 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, vshader)); |
| 587 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, fshader)); | 586 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, fshader)); |
| 588 program_info->Link(NULL, NULL, NULL, NULL); | 587 program_info->Link(); |
| 589 GLint value = 0; | 588 GLint value = 0; |
| 590 program_info->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value); | 589 program_info->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value); |
| 591 EXPECT_EQ(3, value); | 590 EXPECT_EQ(3, value); |
| 592 // Check that we skipped the "gl_" uniform. | 591 // Check that we skipped the "gl_" uniform. |
| 593 program_info->GetProgramiv(GL_ACTIVE_UNIFORMS, &value); | 592 program_info->GetProgramiv(GL_ACTIVE_UNIFORMS, &value); |
| 594 EXPECT_EQ(2, value); | 593 EXPECT_EQ(2, value); |
| 595 // Check that our max length adds room for the array spec and is not as long | 594 // Check that our max length adds room for the array spec and is not as long |
| 596 // as the "gl_" uniform we skipped. | 595 // as the "gl_" uniform we skipped. |
| 597 // +4u is to account for "gl_" and NULL terminator. | 596 // +4u is to account for "gl_" and NULL terminator. |
| 598 program_info->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value); | 597 program_info->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 const size_t kNumUniforms = arraysize(kUniforms); | 671 const size_t kNumUniforms = arraysize(kUniforms); |
| 673 static const GLuint kClientProgramId = 1234; | 672 static const GLuint kClientProgramId = 1234; |
| 674 static const GLuint kServiceProgramId = 5679; | 673 static const GLuint kServiceProgramId = 5679; |
| 675 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, | 674 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, |
| 676 kServiceProgramId); | 675 kServiceProgramId); |
| 677 ProgramManager::ProgramInfo* program_info = manager_.CreateProgramInfo( | 676 ProgramManager::ProgramInfo* program_info = manager_.CreateProgramInfo( |
| 678 kClientProgramId, kServiceProgramId); | 677 kClientProgramId, kServiceProgramId); |
| 679 ASSERT_TRUE(program_info != NULL); | 678 ASSERT_TRUE(program_info != NULL); |
| 680 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, vshader)); | 679 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, vshader)); |
| 681 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, fshader)); | 680 EXPECT_TRUE(program_info->AttachShader(&shader_manager_, fshader)); |
| 682 program_info->Link(NULL, NULL, NULL, NULL); | 681 program_info->Link(); |
| 683 // Check that we got the good type, not the bad. | 682 // Check that we got the good type, not the bad. |
| 684 // Check Attribs | 683 // Check Attribs |
| 685 for (unsigned index = 0; index < kNumAttribs; ++index) { | 684 for (unsigned index = 0; index < kNumAttribs; ++index) { |
| 686 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = | 685 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = |
| 687 program_info->GetAttribInfo(index); | 686 program_info->GetAttribInfo(index); |
| 688 ASSERT_TRUE(attrib_info != NULL); | 687 ASSERT_TRUE(attrib_info != NULL); |
| 689 ShaderTranslator::VariableMap::const_iterator it = attrib_map.find( | 688 ShaderTranslator::VariableMap::const_iterator it = attrib_map.find( |
| 690 attrib_info->name); | 689 attrib_info->name); |
| 691 ASSERT_TRUE(it != attrib_map.end()); | 690 ASSERT_TRUE(it != attrib_map.end()); |
| 692 EXPECT_EQ(it->first, attrib_info->name); | 691 EXPECT_EQ(it->first, attrib_info->name); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 kUniform3FakeLocation, | 990 kUniform3FakeLocation, |
| 992 kUniform3RealLocation, | 991 kUniform3RealLocation, |
| 993 kUniform3DesiredLocation, | 992 kUniform3DesiredLocation, |
| 994 kUniform3GoodName, | 993 kUniform3GoodName, |
| 995 }, | 994 }, |
| 996 }; | 995 }; |
| 997 const size_t kNumAttribs = arraysize(kAttribs); | 996 const size_t kNumAttribs = arraysize(kAttribs); |
| 998 const size_t kNumUniforms = arraysize(kUniforms); | 997 const size_t kNumUniforms = arraysize(kUniforms); |
| 999 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, | 998 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, |
| 1000 kServiceProgramId); | 999 kServiceProgramId); |
| 1001 program_info->Link(NULL, NULL, NULL, NULL); | 1000 program_info->Link(); |
| 1002 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms); | 1001 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms); |
| 1003 manager_.ClearUniforms(program_info); | 1002 manager_.ClearUniforms(program_info); |
| 1004 } | 1003 } |
| 1005 } | 1004 } |
| 1006 | 1005 |
| 1007 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) { | 1006 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) { |
| 1008 const GLuint kVShaderClientId = 2001; | 1007 const GLuint kVShaderClientId = 2001; |
| 1009 const GLuint kFShaderClientId = 2002; | 1008 const GLuint kFShaderClientId = 2002; |
| 1010 const GLuint kVShaderServiceId = 3001; | 1009 const GLuint kVShaderServiceId = 3001; |
| 1011 const GLuint kFShaderServiceId = 3002; | 1010 const GLuint kFShaderServiceId = 3002; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 kUniform3RealLocation, | 1062 kUniform3RealLocation, |
| 1064 kUniform3DesiredLocation, | 1063 kUniform3DesiredLocation, |
| 1065 kUniform3GoodName, | 1064 kUniform3GoodName, |
| 1066 }, | 1065 }, |
| 1067 }; | 1066 }; |
| 1068 | 1067 |
| 1069 const size_t kNumAttribs = arraysize(kAttribs); | 1068 const size_t kNumAttribs = arraysize(kAttribs); |
| 1070 const size_t kNumUniforms = arraysize(kUniforms); | 1069 const size_t kNumUniforms = arraysize(kUniforms); |
| 1071 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, | 1070 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms, |
| 1072 kServiceProgramId); | 1071 kServiceProgramId); |
| 1073 program_info->Link(NULL, NULL, NULL, NULL); | 1072 program_info->Link(); |
| 1074 | 1073 |
| 1075 EXPECT_EQ(kUniform1DesiredLocation, | 1074 EXPECT_EQ(kUniform1DesiredLocation, |
| 1076 program_info->GetUniformFakeLocation(kUniform1Name)); | 1075 program_info->GetUniformFakeLocation(kUniform1Name)); |
| 1077 EXPECT_EQ(kUniform3DesiredLocation, | 1076 EXPECT_EQ(kUniform3DesiredLocation, |
| 1078 program_info->GetUniformFakeLocation(kUniform3BadName)); | 1077 program_info->GetUniformFakeLocation(kUniform3BadName)); |
| 1079 EXPECT_EQ(kUniform3DesiredLocation, | 1078 EXPECT_EQ(kUniform3DesiredLocation, |
| 1080 program_info->GetUniformFakeLocation(kUniform3GoodName)); | 1079 program_info->GetUniformFakeLocation(kUniform3GoodName)); |
| 1081 } | 1080 } |
| 1082 | 1081 |
| 1083 class ProgramManagerWithCacheTest : public testing::Test { | |
| 1084 public: | |
| 1085 static const GLuint kClientProgramId = 1; | |
| 1086 static const GLuint kServiceProgramId = 10; | |
| 1087 static const GLuint kVertexShaderClientId = 2; | |
| 1088 static const GLuint kFragmentShaderClientId = 20; | |
| 1089 static const GLuint kVertexShaderServiceId = 3; | |
| 1090 static const GLuint kFragmentShaderServiceId = 30; | |
| 1091 | |
| 1092 ProgramManagerWithCacheTest() | |
| 1093 : cache_(new MockProgramCache()), | |
| 1094 manager_(cache_.get()), | |
| 1095 vertex_shader_(NULL), | |
| 1096 fragment_shader_(NULL), | |
| 1097 program_info_(NULL) { | |
| 1098 } | |
| 1099 ~ProgramManagerWithCacheTest() { | |
| 1100 manager_.Destroy(false); | |
| 1101 shader_manager_.Destroy(false); | |
| 1102 } | |
| 1103 | |
| 1104 protected: | |
| 1105 virtual void SetUp() { | |
| 1106 gl_.reset(new StrictMock<gfx::MockGLInterface>()); | |
| 1107 ::gfx::GLInterface::SetGLInterface(gl_.get()); | |
| 1108 | |
| 1109 vertex_shader_ = shader_manager_.CreateShaderInfo( | |
| 1110 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER); | |
| 1111 fragment_shader_ = shader_manager_.CreateShaderInfo( | |
| 1112 kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER); | |
| 1113 ASSERT_TRUE(vertex_shader_ != NULL); | |
| 1114 ASSERT_TRUE(fragment_shader_ != NULL); | |
| 1115 vertex_shader_->UpdateSource("lka asjf bjajsdfj"); | |
| 1116 fragment_shader_->UpdateSource("lka asjf a fasgag 3rdsf3 bjajsdfj"); | |
| 1117 | |
| 1118 program_info_ = manager_.CreateProgramInfo( | |
| 1119 kClientProgramId, kServiceProgramId); | |
| 1120 ASSERT_TRUE(program_info_ != NULL); | |
| 1121 | |
| 1122 program_info_->AttachShader(&shader_manager_, vertex_shader_); | |
| 1123 program_info_->AttachShader(&shader_manager_, fragment_shader_); | |
| 1124 } | |
| 1125 | |
| 1126 virtual void TearDown() { | |
| 1127 ::gfx::GLInterface::SetGLInterface(NULL); | |
| 1128 } | |
| 1129 | |
| 1130 void SetShadersCompiled() { | |
| 1131 cache_->ShaderCompilationSucceeded(*vertex_shader_->source()); | |
| 1132 cache_->ShaderCompilationSucceeded(*fragment_shader_->source()); | |
| 1133 vertex_shader_->SetStatus(true, NULL, NULL); | |
| 1134 fragment_shader_->SetStatus(true, NULL, NULL); | |
| 1135 vertex_shader_->FlagSourceAsCompiled(true); | |
| 1136 fragment_shader_->FlagSourceAsCompiled(true); | |
| 1137 } | |
| 1138 | |
| 1139 void SetShadersNotCompiledButCached() { | |
| 1140 SetShadersCompiled(); | |
| 1141 vertex_shader_->FlagSourceAsCompiled(false); | |
| 1142 fragment_shader_->FlagSourceAsCompiled(false); | |
| 1143 } | |
| 1144 | |
| 1145 void SetProgramCached() { | |
| 1146 cache_->LinkedProgramCacheSuccess( | |
| 1147 vertex_shader_->source()->c_str(), | |
| 1148 fragment_shader_->source()->c_str(), | |
| 1149 &program_info_->bind_attrib_location_map()); | |
| 1150 } | |
| 1151 | |
| 1152 void SetExpectationsForProgramCached() { | |
| 1153 SetExpectationsForProgramCached(program_info_, | |
| 1154 vertex_shader_, | |
| 1155 fragment_shader_); | |
| 1156 } | |
| 1157 | |
| 1158 void SetExpectationsForProgramCached( | |
| 1159 ProgramManager::ProgramInfo* program_info, | |
| 1160 ShaderManager::ShaderInfo* vertex_shader, | |
| 1161 ShaderManager::ShaderInfo* fragment_shader) { | |
| 1162 EXPECT_CALL(*cache_.get(), SaveLinkedProgram( | |
| 1163 program_info->service_id(), | |
| 1164 vertex_shader, | |
| 1165 fragment_shader, | |
| 1166 &program_info->bind_attrib_location_map())).Times(1); | |
| 1167 } | |
| 1168 | |
| 1169 void SetExpectationsForNotCachingProgram() { | |
| 1170 SetExpectationsForNotCachingProgram(program_info_, | |
| 1171 vertex_shader_, | |
| 1172 fragment_shader_); | |
| 1173 } | |
| 1174 | |
| 1175 void SetExpectationsForNotCachingProgram( | |
| 1176 ProgramManager::ProgramInfo* program_info, | |
| 1177 ShaderManager::ShaderInfo* vertex_shader, | |
| 1178 ShaderManager::ShaderInfo* fragment_shader) { | |
| 1179 EXPECT_CALL(*cache_.get(), SaveLinkedProgram( | |
| 1180 program_info->service_id(), | |
| 1181 vertex_shader, | |
| 1182 fragment_shader, | |
| 1183 &program_info->bind_attrib_location_map())).Times(0); | |
| 1184 } | |
| 1185 | |
| 1186 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) { | |
| 1187 SetExpectationsForProgramLoad(kServiceProgramId, | |
| 1188 program_info_, | |
| 1189 vertex_shader_, | |
| 1190 fragment_shader_, | |
| 1191 result); | |
| 1192 } | |
| 1193 | |
| 1194 void SetExpectationsForProgramLoad( | |
| 1195 GLuint service_program_id, | |
| 1196 ProgramManager::ProgramInfo* program_info, | |
| 1197 ShaderManager::ShaderInfo* vertex_shader, | |
| 1198 ShaderManager::ShaderInfo* fragment_shader, | |
| 1199 ProgramCache::ProgramLoadResult result) { | |
| 1200 EXPECT_CALL(*cache_.get(), | |
| 1201 LoadLinkedProgram(service_program_id, | |
| 1202 vertex_shader, | |
| 1203 fragment_shader, | |
| 1204 &program_info->bind_attrib_location_map())) | |
| 1205 .WillOnce(Return(result)); | |
| 1206 } | |
| 1207 | |
| 1208 void SetExpectationsForProgramLoadSuccess() { | |
| 1209 SetExpectationsForProgramLoadSuccess(kServiceProgramId); | |
| 1210 } | |
| 1211 | |
| 1212 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) { | |
| 1213 TestHelper::SetupProgramSuccessExpectations(gl_.get(), | |
| 1214 NULL, | |
| 1215 0, | |
| 1216 NULL, | |
| 1217 0, | |
| 1218 service_program_id); | |
| 1219 } | |
| 1220 | |
| 1221 void SetExpectationsForProgramLink() { | |
| 1222 SetExpectationsForProgramLink(kServiceProgramId); | |
| 1223 } | |
| 1224 | |
| 1225 void SetExpectationsForProgramLink(GLuint service_program_id) { | |
| 1226 TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id); | |
| 1227 } | |
| 1228 | |
| 1229 void SetExpectationsForSuccessCompile( | |
| 1230 const ShaderManager::ShaderInfo* shader) { | |
| 1231 const GLuint shader_id = shader->service_id(); | |
| 1232 const char* src = shader->source()->c_str(); | |
| 1233 EXPECT_CALL(*gl_.get(), | |
| 1234 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1); | |
| 1235 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1); | |
| 1236 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _)) | |
| 1237 .WillOnce(SetArgumentPointee<2>(GL_TRUE)); | |
| 1238 } | |
| 1239 | |
| 1240 void SetExpectationsForNoCompile(const ShaderManager::ShaderInfo* shader) { | |
| 1241 const GLuint shader_id = shader->service_id(); | |
| 1242 const char* src = shader->source()->c_str(); | |
| 1243 EXPECT_CALL(*gl_.get(), | |
| 1244 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0); | |
| 1245 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0); | |
| 1246 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _)) | |
| 1247 .Times(0); | |
| 1248 } | |
| 1249 | |
| 1250 void SetExpectationsForErrorCompile(const ShaderManager::ShaderInfo* shader) { | |
| 1251 const GLuint shader_id = shader->service_id(); | |
| 1252 const char* src = shader->source()->c_str(); | |
| 1253 EXPECT_CALL(*gl_.get(), | |
| 1254 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1); | |
| 1255 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1); | |
| 1256 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _)) | |
| 1257 .WillOnce(SetArgumentPointee<2>(GL_FALSE)); | |
| 1258 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _)) | |
| 1259 .WillOnce(SetArgumentPointee<2>(0)); | |
| 1260 EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _)) | |
| 1261 .Times(1); | |
| 1262 } | |
| 1263 | |
| 1264 scoped_ptr<StrictMock<gfx::MockGLInterface> > gl_; | |
| 1265 | |
| 1266 scoped_ptr<MockProgramCache> cache_; | |
| 1267 ProgramManager manager_; | |
| 1268 | |
| 1269 ShaderManager::ShaderInfo* vertex_shader_; | |
| 1270 ShaderManager::ShaderInfo* fragment_shader_; | |
| 1271 ProgramManager::ProgramInfo* program_info_; | |
| 1272 ShaderManager shader_manager_; | |
| 1273 }; | |
| 1274 | |
| 1275 // GCC requires these declarations, but MSVC requires they not be present | |
| 1276 #ifndef COMPILER_MSVC | |
| 1277 const GLuint ProgramManagerWithCacheTest::kClientProgramId; | |
| 1278 const GLuint ProgramManagerWithCacheTest::kServiceProgramId; | |
| 1279 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId; | |
| 1280 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId; | |
| 1281 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId; | |
| 1282 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId; | |
| 1283 #endif | |
| 1284 | |
| 1285 TEST_F(ProgramManagerWithCacheTest, CacheSuccessAfterShaderCompile) { | |
| 1286 SetExpectationsForSuccessCompile(vertex_shader_); | |
| 1287 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1288 manager_.DoCompileShader(vertex_shader_, NULL, info.get()); | |
| 1289 EXPECT_EQ(ProgramCache::COMPILATION_SUCCEEDED, | |
| 1290 cache_->GetShaderCompilationStatus(*vertex_shader_->source())); | |
| 1291 } | |
| 1292 | |
| 1293 TEST_F(ProgramManagerWithCacheTest, CacheUnknownAfterShaderError) { | |
| 1294 SetExpectationsForErrorCompile(vertex_shader_); | |
| 1295 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1296 manager_.DoCompileShader(vertex_shader_, NULL, info.get()); | |
| 1297 EXPECT_EQ(ProgramCache::COMPILATION_UNKNOWN, | |
| 1298 cache_->GetShaderCompilationStatus(*vertex_shader_->source())); | |
| 1299 } | |
| 1300 | |
| 1301 TEST_F(ProgramManagerWithCacheTest, NoCompileWhenShaderCached) { | |
| 1302 cache_->ShaderCompilationSucceeded(vertex_shader_->source()->c_str()); | |
| 1303 SetExpectationsForNoCompile(vertex_shader_); | |
| 1304 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1305 manager_.DoCompileShader(vertex_shader_, NULL, info.get()); | |
| 1306 } | |
| 1307 | |
| 1308 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) { | |
| 1309 SetShadersCompiled(); | |
| 1310 SetExpectationsForProgramLink(); | |
| 1311 SetExpectationsForProgramCached(); | |
| 1312 EXPECT_TRUE(program_info_->Link(NULL, NULL, NULL, NULL)); | |
| 1313 } | |
| 1314 | |
| 1315 TEST_F(ProgramManagerWithCacheTest, CompileShaderOnLinkCacheMiss) { | |
| 1316 SetShadersCompiled(); | |
| 1317 vertex_shader_->FlagSourceAsCompiled(false); | |
| 1318 | |
| 1319 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1320 | |
| 1321 SetExpectationsForSuccessCompile(vertex_shader_); | |
| 1322 SetExpectationsForProgramLink(); | |
| 1323 SetExpectationsForProgramCached(); | |
| 1324 EXPECT_TRUE(program_info_->Link(&shader_manager_, NULL, NULL, info.get())); | |
| 1325 } | |
| 1326 | |
| 1327 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) { | |
| 1328 SetShadersNotCompiledButCached(); | |
| 1329 SetProgramCached(); | |
| 1330 | |
| 1331 SetExpectationsForNoCompile(vertex_shader_); | |
| 1332 SetExpectationsForNoCompile(fragment_shader_); | |
| 1333 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS); | |
| 1334 SetExpectationsForNotCachingProgram(); | |
| 1335 SetExpectationsForProgramLoadSuccess(); | |
| 1336 | |
| 1337 EXPECT_TRUE(program_info_->Link(NULL, NULL, NULL, NULL)); | |
| 1338 } | |
| 1339 | |
| 1340 TEST_F(ProgramManagerWithCacheTest, CompileAndLinkOnProgramCacheError) { | |
| 1341 SetShadersNotCompiledButCached(); | |
| 1342 SetProgramCached(); | |
| 1343 | |
| 1344 SetExpectationsForSuccessCompile(vertex_shader_); | |
| 1345 SetExpectationsForSuccessCompile(fragment_shader_); | |
| 1346 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_FAILURE); | |
| 1347 SetExpectationsForProgramLink(); | |
| 1348 SetExpectationsForProgramCached(); | |
| 1349 | |
| 1350 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1351 EXPECT_TRUE(program_info_->Link(&shader_manager_, NULL, NULL, info.get())); | |
| 1352 } | |
| 1353 | |
| 1354 TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeNoCompile) { | |
| 1355 SetShadersNotCompiledButCached(); | |
| 1356 SetProgramCached(); | |
| 1357 | |
| 1358 const GLuint kNewShaderClientId = 4; | |
| 1359 const GLuint kNewShaderServiceId = 40; | |
| 1360 const GLuint kNewProgramClientId = 5; | |
| 1361 const GLuint kNewProgramServiceId = 50; | |
| 1362 | |
| 1363 ShaderManager::ShaderInfo* new_vertex_shader = | |
| 1364 shader_manager_.CreateShaderInfo(kNewShaderClientId, | |
| 1365 kNewShaderServiceId, | |
| 1366 GL_VERTEX_SHADER); | |
| 1367 | |
| 1368 const std::string original_source = *vertex_shader_->source(); | |
| 1369 new_vertex_shader->UpdateSource(original_source.c_str()); | |
| 1370 | |
| 1371 ProgramManager::ProgramInfo* program_info = manager_.CreateProgramInfo( | |
| 1372 kNewProgramClientId, kNewProgramServiceId); | |
| 1373 ASSERT_TRUE(program_info != NULL); | |
| 1374 program_info->AttachShader(&shader_manager_, new_vertex_shader); | |
| 1375 program_info->AttachShader(&shader_manager_, fragment_shader_); | |
| 1376 | |
| 1377 SetExpectationsForNoCompile(new_vertex_shader); | |
| 1378 | |
| 1379 manager_.DoCompileShader(new_vertex_shader, NULL, NULL); | |
| 1380 | |
| 1381 new_vertex_shader->UpdateSource("different!"); | |
| 1382 EXPECT_EQ(original_source, | |
| 1383 *new_vertex_shader->deferred_compilation_source()); | |
| 1384 | |
| 1385 EXPECT_FALSE(new_vertex_shader->source_compiled()); | |
| 1386 EXPECT_FALSE(fragment_shader_->source_compiled()); | |
| 1387 | |
| 1388 SetExpectationsForNoCompile(fragment_shader_); | |
| 1389 SetExpectationsForNotCachingProgram(program_info, | |
| 1390 new_vertex_shader, | |
| 1391 fragment_shader_); | |
| 1392 SetExpectationsForProgramLoad(kNewProgramServiceId, | |
| 1393 program_info, | |
| 1394 new_vertex_shader, | |
| 1395 fragment_shader_, | |
| 1396 ProgramCache::PROGRAM_LOAD_SUCCESS); | |
| 1397 SetExpectationsForProgramLoadSuccess(kNewProgramServiceId); | |
| 1398 | |
| 1399 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1400 EXPECT_TRUE(program_info->Link(&shader_manager_, NULL, NULL, info.get())); | |
| 1401 } | |
| 1402 | |
| 1403 TEST_F(ProgramManagerWithCacheTest, CorrectCompileOnSourceChangeWithCompile) { | |
| 1404 SetShadersNotCompiledButCached(); | |
| 1405 SetProgramCached(); | |
| 1406 | |
| 1407 const GLuint kNewShaderClientId = 4; | |
| 1408 const GLuint kNewShaderServiceId = 40; | |
| 1409 const GLuint kNewProgramClientId = 5; | |
| 1410 const GLuint kNewProgramServiceId = 50; | |
| 1411 | |
| 1412 ShaderManager::ShaderInfo* new_vertex_shader = | |
| 1413 shader_manager_.CreateShaderInfo(kNewShaderClientId, | |
| 1414 kNewShaderServiceId, | |
| 1415 GL_VERTEX_SHADER); | |
| 1416 | |
| 1417 new_vertex_shader->UpdateSource(vertex_shader_->source()->c_str()); | |
| 1418 | |
| 1419 ProgramManager::ProgramInfo* program_info = manager_.CreateProgramInfo( | |
| 1420 kNewProgramClientId, kNewProgramServiceId); | |
| 1421 ASSERT_TRUE(program_info != NULL); | |
| 1422 program_info->AttachShader(&shader_manager_, new_vertex_shader); | |
| 1423 program_info->AttachShader(&shader_manager_, fragment_shader_); | |
| 1424 | |
| 1425 SetExpectationsForNoCompile(new_vertex_shader); | |
| 1426 | |
| 1427 manager_.DoCompileShader(new_vertex_shader, NULL, NULL); | |
| 1428 | |
| 1429 const std::string differentSource = "different!"; | |
| 1430 new_vertex_shader->UpdateSource(differentSource.c_str()); | |
| 1431 SetExpectationsForSuccessCompile(new_vertex_shader); | |
| 1432 | |
| 1433 FeatureInfo::Ref info(new FeatureInfo()); | |
| 1434 manager_.DoCompileShader(new_vertex_shader, NULL, info.get()); | |
| 1435 EXPECT_EQ(differentSource, | |
| 1436 *new_vertex_shader->deferred_compilation_source()); | |
| 1437 | |
| 1438 EXPECT_TRUE(new_vertex_shader->source_compiled()); | |
| 1439 EXPECT_FALSE(fragment_shader_->source_compiled()); | |
| 1440 | |
| 1441 // so we don't recompile because we were pending originally | |
| 1442 SetExpectationsForNoCompile(new_vertex_shader); | |
| 1443 SetExpectationsForSuccessCompile(fragment_shader_); | |
| 1444 SetExpectationsForProgramCached(program_info, | |
| 1445 new_vertex_shader, | |
| 1446 fragment_shader_); | |
| 1447 SetExpectationsForProgramLink(kNewProgramServiceId); | |
| 1448 | |
| 1449 EXPECT_TRUE(program_info->Link(&shader_manager_, NULL, NULL, info.get())); | |
| 1450 } | |
| 1451 | |
| 1452 } // namespace gles2 | 1082 } // namespace gles2 |
| 1453 } // namespace gpu | 1083 } // namespace gpu |
| 1084 |
| 1085 |
| OLD | NEW |