Handle account removal correctly on all platforms.
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blob3cca2637e230933146ac5aa38eb88331270e356e
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
3 // found in the LICENSE file.
5 #include "gpu/command_buffer/service/program_manager.h"
7 #include <algorithm>
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "gpu/command_buffer/common/gles2_cmd_format.h"
13 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
14 #include "gpu/command_buffer/service/common_decoder.h"
15 #include "gpu/command_buffer/service/feature_info.h"
16 #include "gpu/command_buffer/service/gpu_service_test.h"
17 #include "gpu/command_buffer/service/mocks.h"
18 #include "gpu/command_buffer/service/shader_manager.h"
19 #include "gpu/command_buffer/service/test_helper.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gl/gl_mock.h"
23 using ::testing::_;
24 using ::testing::DoAll;
25 using ::testing::InSequence;
26 using ::testing::MatcherCast;
27 using ::testing::Pointee;
28 using ::testing::Return;
29 using ::testing::ReturnRef;
30 using ::testing::SetArrayArgument;
31 using ::testing::SetArgumentPointee;
32 using ::testing::StrEq;
34 namespace gpu {
35 namespace gles2 {
37 namespace {
38 const uint32 kMaxVaryingVectors = 8;
40 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
41 } // namespace anonymous
43 class ProgramManagerTest : public GpuServiceTest {
44 public:
45 ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
46 virtual ~ProgramManagerTest() {
47 manager_.Destroy(false);
50 protected:
51 ProgramManager manager_;
54 TEST_F(ProgramManagerTest, Basic) {
55 const GLuint kClient1Id = 1;
56 const GLuint kService1Id = 11;
57 const GLuint kClient2Id = 2;
58 // Check we can create program.
59 manager_.CreateProgram(kClient1Id, kService1Id);
60 // Check program got created.
61 Program* program1 = manager_.GetProgram(kClient1Id);
62 ASSERT_TRUE(program1 != NULL);
63 GLuint client_id = 0;
64 EXPECT_TRUE(manager_.GetClientId(program1->service_id(), &client_id));
65 EXPECT_EQ(kClient1Id, client_id);
66 // Check we get nothing for a non-existent program.
67 EXPECT_TRUE(manager_.GetProgram(kClient2Id) == NULL);
70 TEST_F(ProgramManagerTest, Destroy) {
71 const GLuint kClient1Id = 1;
72 const GLuint kService1Id = 11;
73 // Check we can create program.
74 Program* program0 = manager_.CreateProgram(kClient1Id, kService1Id);
75 ASSERT_TRUE(program0 != NULL);
76 // Check program got created.
77 Program* program1 = manager_.GetProgram(kClient1Id);
78 ASSERT_EQ(program0, program1);
79 EXPECT_CALL(*gl_, DeleteProgram(kService1Id))
80 .Times(1)
81 .RetiresOnSaturation();
82 manager_.Destroy(true);
83 // Check the resources were released.
84 program1 = manager_.GetProgram(kClient1Id);
85 ASSERT_TRUE(program1 == NULL);
88 TEST_F(ProgramManagerTest, DeleteBug) {
89 ShaderManager shader_manager;
90 const GLuint kClient1Id = 1;
91 const GLuint kClient2Id = 2;
92 const GLuint kService1Id = 11;
93 const GLuint kService2Id = 12;
94 // Check we can create program.
95 scoped_refptr<Program> program1(
96 manager_.CreateProgram(kClient1Id, kService1Id));
97 scoped_refptr<Program> program2(
98 manager_.CreateProgram(kClient2Id, kService2Id));
99 // Check program got created.
100 ASSERT_TRUE(program1.get());
101 ASSERT_TRUE(program2.get());
102 manager_.UseProgram(program1.get());
103 manager_.MarkAsDeleted(&shader_manager, program1.get());
104 // Program will be deleted when last ref is released.
105 EXPECT_CALL(*gl_, DeleteProgram(kService2Id))
106 .Times(1)
107 .RetiresOnSaturation();
108 manager_.MarkAsDeleted(&shader_manager, program2.get());
109 EXPECT_TRUE(manager_.IsOwned(program1.get()));
110 EXPECT_FALSE(manager_.IsOwned(program2.get()));
113 TEST_F(ProgramManagerTest, Program) {
114 const GLuint kClient1Id = 1;
115 const GLuint kService1Id = 11;
116 // Check we can create program.
117 Program* program1 = manager_.CreateProgram(
118 kClient1Id, kService1Id);
119 ASSERT_TRUE(program1);
120 EXPECT_EQ(kService1Id, program1->service_id());
121 EXPECT_FALSE(program1->InUse());
122 EXPECT_FALSE(program1->IsValid());
123 EXPECT_FALSE(program1->IsDeleted());
124 EXPECT_FALSE(program1->CanLink());
125 EXPECT_TRUE(program1->log_info() == NULL);
128 class ProgramManagerWithShaderTest : public GpuServiceTest {
129 public:
130 ProgramManagerWithShaderTest()
131 : manager_(NULL, kMaxVaryingVectors), program_(NULL) {
134 virtual ~ProgramManagerWithShaderTest() {
135 manager_.Destroy(false);
136 shader_manager_.Destroy(false);
139 static const GLint kNumVertexAttribs = 16;
141 static const GLuint kClientProgramId = 123;
142 static const GLuint kServiceProgramId = 456;
143 static const GLuint kVertexShaderClientId = 201;
144 static const GLuint kFragmentShaderClientId = 202;
145 static const GLuint kVertexShaderServiceId = 301;
146 static const GLuint kFragmentShaderServiceId = 302;
148 static const char* kAttrib1Name;
149 static const char* kAttrib2Name;
150 static const char* kAttrib3Name;
151 static const GLint kAttrib1Size = 1;
152 static const GLint kAttrib2Size = 1;
153 static const GLint kAttrib3Size = 1;
154 static const int kAttrib1Precision = SH_PRECISION_MEDIUMP;
155 static const int kAttrib2Precision = SH_PRECISION_HIGHP;
156 static const int kAttrib3Precision = SH_PRECISION_LOWP;
157 static const int kAttribStaticUse = 0;
158 static const GLint kAttrib1Location = 0;
159 static const GLint kAttrib2Location = 1;
160 static const GLint kAttrib3Location = 2;
161 static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
162 static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
163 static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
164 static const GLint kInvalidAttribLocation = 30;
165 static const GLint kBadAttribIndex = kNumVertexAttribs;
167 static const char* kUniform1Name;
168 static const char* kUniform2Name;
169 static const char* kUniform3BadName;
170 static const char* kUniform3GoodName;
171 static const GLint kUniform1Size = 1;
172 static const GLint kUniform2Size = 3;
173 static const GLint kUniform3Size = 2;
174 static const int kUniform1Precision = SH_PRECISION_LOWP;
175 static const int kUniform2Precision = SH_PRECISION_MEDIUMP;
176 static const int kUniform3Precision = SH_PRECISION_HIGHP;
177 static const int kUniform1StaticUse = 1;
178 static const int kUniform2StaticUse = 1;
179 static const int kUniform3StaticUse = 1;
180 static const GLint kUniform1FakeLocation = 0; // These are hard coded
181 static const GLint kUniform2FakeLocation = 1; // to match
182 static const GLint kUniform3FakeLocation = 2; // ProgramManager.
183 static const GLint kUniform1RealLocation = 11;
184 static const GLint kUniform2RealLocation = 22;
185 static const GLint kUniform3RealLocation = 33;
186 static const GLint kUniform1DesiredLocation = -1;
187 static const GLint kUniform2DesiredLocation = -1;
188 static const GLint kUniform3DesiredLocation = -1;
189 static const GLenum kUniform1Type = GL_FLOAT_VEC4;
190 static const GLenum kUniform2Type = GL_INT_VEC2;
191 static const GLenum kUniform3Type = GL_FLOAT_VEC3;
192 static const GLint kInvalidUniformLocation = 30;
193 static const GLint kBadUniformIndex = 1000;
195 static const size_t kNumAttribs;
196 static const size_t kNumUniforms;
198 protected:
199 typedef TestHelper::AttribInfo AttribInfo;
200 typedef TestHelper::UniformInfo UniformInfo;
202 typedef enum {
203 kVarUniform,
204 kVarVarying,
205 kVarAttribute
206 } VarCategory;
208 typedef struct {
209 int type;
210 int size;
211 int precision;
212 int static_use;
213 std::string name;
214 VarCategory category;
215 } VarInfo;
217 virtual void SetUp() {
218 GpuServiceTest::SetUp();
220 SetupDefaultShaderExpectations();
222 Shader* vertex_shader = shader_manager_.CreateShader(
223 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
224 Shader* fragment_shader =
225 shader_manager_.CreateShader(
226 kFragmentShaderClientId, kFragmentShaderServiceId,
227 GL_FRAGMENT_SHADER);
228 ASSERT_TRUE(vertex_shader != NULL);
229 ASSERT_TRUE(fragment_shader != NULL);
230 TestHelper::SetShaderStates(gl_.get(), vertex_shader, true);
231 TestHelper::SetShaderStates(gl_.get(), fragment_shader, true);
233 program_ = manager_.CreateProgram(
234 kClientProgramId, kServiceProgramId);
235 ASSERT_TRUE(program_ != NULL);
237 program_->AttachShader(&shader_manager_, vertex_shader);
238 program_->AttachShader(&shader_manager_, fragment_shader);
239 program_->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
240 base::Bind(&ShaderCacheCb));
243 void SetupShader(AttribInfo* attribs, size_t num_attribs,
244 UniformInfo* uniforms, size_t num_uniforms,
245 GLuint service_id) {
246 TestHelper::SetupShader(
247 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
250 void SetupDefaultShaderExpectations() {
251 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
252 kServiceProgramId);
255 void SetupExpectationsForClearingUniforms(
256 UniformInfo* uniforms, size_t num_uniforms) {
257 TestHelper::SetupExpectationsForClearingUniforms(
258 gl_.get(), uniforms, num_uniforms);
261 // Return true if link status matches expected_link_status
262 bool LinkAsExpected(Program* program,
263 bool expected_link_status) {
264 GLuint service_id = program->service_id();
265 if (expected_link_status) {
266 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
267 service_id);
269 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
270 base::Bind(&ShaderCacheCb));
271 GLint link_status;
272 program->GetProgramiv(GL_LINK_STATUS, &link_status);
273 return (static_cast<bool>(link_status) == expected_link_status);
276 Program* SetupShaderVariableTest(const VarInfo* vertex_variables,
277 size_t vertex_variable_size,
278 const VarInfo* fragment_variables,
279 size_t fragment_variable_size) {
280 // Set up shader
281 const GLuint kVShaderClientId = 1;
282 const GLuint kVShaderServiceId = 11;
283 const GLuint kFShaderClientId = 2;
284 const GLuint kFShaderServiceId = 12;
286 ShaderTranslator::VariableMap vertex_attrib_map;
287 ShaderTranslator::VariableMap vertex_uniform_map;
288 ShaderTranslator::VariableMap vertex_varying_map;
289 for (size_t ii = 0; ii < vertex_variable_size; ++ii) {
290 ShaderTranslator::VariableMap* map = NULL;
291 switch (vertex_variables[ii].category) {
292 case kVarAttribute:
293 map = &vertex_attrib_map;
294 break;
295 case kVarUniform:
296 map = &vertex_uniform_map;
297 break;
298 case kVarVarying:
299 map = &vertex_varying_map;
300 break;
301 default:
302 NOTREACHED();
304 (*map)[vertex_variables[ii].name] =
305 ShaderTranslator::VariableInfo(vertex_variables[ii].type,
306 vertex_variables[ii].size,
307 vertex_variables[ii].precision,
308 vertex_variables[ii].static_use,
309 vertex_variables[ii].name);
312 ShaderTranslator::VariableMap frag_attrib_map;
313 ShaderTranslator::VariableMap frag_uniform_map;
314 ShaderTranslator::VariableMap frag_varying_map;
315 for (size_t ii = 0; ii < fragment_variable_size; ++ii) {
316 ShaderTranslator::VariableMap* map = NULL;
317 switch (fragment_variables[ii].category) {
318 case kVarAttribute:
319 map = &frag_attrib_map;
320 break;
321 case kVarUniform:
322 map = &frag_uniform_map;
323 break;
324 case kVarVarying:
325 map = &frag_varying_map;
326 break;
327 default:
328 NOTREACHED();
330 (*map)[fragment_variables[ii].name] =
331 ShaderTranslator::VariableInfo(fragment_variables[ii].type,
332 fragment_variables[ii].size,
333 fragment_variables[ii].precision,
334 fragment_variables[ii].static_use,
335 fragment_variables[ii].name);
338 // Check we can create shader.
339 Shader* vshader = shader_manager_.CreateShader(
340 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
341 Shader* fshader = shader_manager_.CreateShader(
342 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
343 // Check shader got created.
344 EXPECT_TRUE(vshader != NULL && fshader != NULL);
345 // Set Status
346 TestHelper::SetShaderStates(
347 gl_.get(), vshader, true, NULL, NULL,
348 &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL);
349 TestHelper::SetShaderStates(
350 gl_.get(), fshader, true, NULL, NULL,
351 &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL);
353 // Set up program
354 const GLuint kClientProgramId = 6666;
355 const GLuint kServiceProgramId = 8888;
356 Program* program =
357 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
358 EXPECT_TRUE(program != NULL);
359 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
360 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
361 return program;
364 static AttribInfo kAttribs[];
365 static UniformInfo kUniforms[];
367 ProgramManager manager_;
368 Program* program_;
369 ShaderManager shader_manager_;
372 ProgramManagerWithShaderTest::AttribInfo
373 ProgramManagerWithShaderTest::kAttribs[] = {
374 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
375 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
376 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
379 // GCC requires these declarations, but MSVC requires they not be present
380 #ifndef COMPILER_MSVC
381 const GLint ProgramManagerWithShaderTest::kNumVertexAttribs;
382 const GLuint ProgramManagerWithShaderTest::kClientProgramId;
383 const GLuint ProgramManagerWithShaderTest::kServiceProgramId;
384 const GLuint ProgramManagerWithShaderTest::kVertexShaderClientId;
385 const GLuint ProgramManagerWithShaderTest::kFragmentShaderClientId;
386 const GLuint ProgramManagerWithShaderTest::kVertexShaderServiceId;
387 const GLuint ProgramManagerWithShaderTest::kFragmentShaderServiceId;
388 const GLint ProgramManagerWithShaderTest::kAttrib1Size;
389 const GLint ProgramManagerWithShaderTest::kAttrib2Size;
390 const GLint ProgramManagerWithShaderTest::kAttrib3Size;
391 const GLint ProgramManagerWithShaderTest::kAttrib1Location;
392 const GLint ProgramManagerWithShaderTest::kAttrib2Location;
393 const GLint ProgramManagerWithShaderTest::kAttrib3Location;
394 const GLenum ProgramManagerWithShaderTest::kAttrib1Type;
395 const GLenum ProgramManagerWithShaderTest::kAttrib2Type;
396 const GLenum ProgramManagerWithShaderTest::kAttrib3Type;
397 const GLint ProgramManagerWithShaderTest::kInvalidAttribLocation;
398 const GLint ProgramManagerWithShaderTest::kBadAttribIndex;
399 const GLint ProgramManagerWithShaderTest::kUniform1Size;
400 const GLint ProgramManagerWithShaderTest::kUniform2Size;
401 const GLint ProgramManagerWithShaderTest::kUniform3Size;
402 const GLint ProgramManagerWithShaderTest::kUniform1FakeLocation;
403 const GLint ProgramManagerWithShaderTest::kUniform2FakeLocation;
404 const GLint ProgramManagerWithShaderTest::kUniform3FakeLocation;
405 const GLint ProgramManagerWithShaderTest::kUniform1RealLocation;
406 const GLint ProgramManagerWithShaderTest::kUniform2RealLocation;
407 const GLint ProgramManagerWithShaderTest::kUniform3RealLocation;
408 const GLint ProgramManagerWithShaderTest::kUniform1DesiredLocation;
409 const GLint ProgramManagerWithShaderTest::kUniform2DesiredLocation;
410 const GLint ProgramManagerWithShaderTest::kUniform3DesiredLocation;
411 const GLenum ProgramManagerWithShaderTest::kUniform1Type;
412 const GLenum ProgramManagerWithShaderTest::kUniform2Type;
413 const GLenum ProgramManagerWithShaderTest::kUniform3Type;
414 const GLint ProgramManagerWithShaderTest::kInvalidUniformLocation;
415 const GLint ProgramManagerWithShaderTest::kBadUniformIndex;
416 #endif
418 const size_t ProgramManagerWithShaderTest::kNumAttribs =
419 arraysize(ProgramManagerWithShaderTest::kAttribs);
421 ProgramManagerWithShaderTest::UniformInfo
422 ProgramManagerWithShaderTest::kUniforms[] = {
423 { kUniform1Name,
424 kUniform1Size,
425 kUniform1Type,
426 kUniform1FakeLocation,
427 kUniform1RealLocation,
428 kUniform1DesiredLocation,
429 kUniform1Name,
431 { kUniform2Name,
432 kUniform2Size,
433 kUniform2Type,
434 kUniform2FakeLocation,
435 kUniform2RealLocation,
436 kUniform2DesiredLocation,
437 kUniform2Name,
439 { kUniform3BadName,
440 kUniform3Size,
441 kUniform3Type,
442 kUniform3FakeLocation,
443 kUniform3RealLocation,
444 kUniform3DesiredLocation,
445 kUniform3GoodName,
449 const size_t ProgramManagerWithShaderTest::kNumUniforms =
450 arraysize(ProgramManagerWithShaderTest::kUniforms);
452 const char* ProgramManagerWithShaderTest::kAttrib1Name = "attrib1";
453 const char* ProgramManagerWithShaderTest::kAttrib2Name = "attrib2";
454 const char* ProgramManagerWithShaderTest::kAttrib3Name = "attrib3";
455 const char* ProgramManagerWithShaderTest::kUniform1Name = "uniform1";
456 // Correctly has array spec.
457 const char* ProgramManagerWithShaderTest::kUniform2Name = "uniform2[0]";
458 // Incorrectly missing array spec.
459 const char* ProgramManagerWithShaderTest::kUniform3BadName = "uniform3";
460 const char* ProgramManagerWithShaderTest::kUniform3GoodName = "uniform3[0]";
462 TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) {
463 const Program* program = manager_.GetProgram(kClientProgramId);
464 ASSERT_TRUE(program != NULL);
465 const Program::AttribInfoVector& infos =
466 program->GetAttribInfos();
467 ASSERT_EQ(kNumAttribs, infos.size());
468 for (size_t ii = 0; ii < kNumAttribs; ++ii) {
469 const Program::VertexAttrib& info = infos[ii];
470 const AttribInfo& expected = kAttribs[ii];
471 EXPECT_EQ(expected.size, info.size);
472 EXPECT_EQ(expected.type, info.type);
473 EXPECT_EQ(expected.location, info.location);
474 EXPECT_STREQ(expected.name, info.name.c_str());
478 TEST_F(ProgramManagerWithShaderTest, GetAttribInfo) {
479 const GLint kValidIndex = 1;
480 const GLint kInvalidIndex = 1000;
481 const Program* program = manager_.GetProgram(kClientProgramId);
482 ASSERT_TRUE(program != NULL);
483 const Program::VertexAttrib* info =
484 program->GetAttribInfo(kValidIndex);
485 ASSERT_TRUE(info != NULL);
486 EXPECT_EQ(kAttrib2Size, info->size);
487 EXPECT_EQ(kAttrib2Type, info->type);
488 EXPECT_EQ(kAttrib2Location, info->location);
489 EXPECT_STREQ(kAttrib2Name, info->name.c_str());
490 EXPECT_TRUE(program->GetAttribInfo(kInvalidIndex) == NULL);
493 TEST_F(ProgramManagerWithShaderTest, GetAttribLocation) {
494 const char* kInvalidName = "foo";
495 const Program* program = manager_.GetProgram(kClientProgramId);
496 ASSERT_TRUE(program != NULL);
497 EXPECT_EQ(kAttrib2Location, program->GetAttribLocation(kAttrib2Name));
498 EXPECT_EQ(-1, program->GetAttribLocation(kInvalidName));
501 TEST_F(ProgramManagerWithShaderTest, GetUniformInfo) {
502 const GLint kInvalidIndex = 1000;
503 const Program* program = manager_.GetProgram(kClientProgramId);
504 ASSERT_TRUE(program != NULL);
505 const Program::UniformInfo* info =
506 program->GetUniformInfo(0);
507 ASSERT_TRUE(info != NULL);
508 EXPECT_EQ(kUniform1Size, info->size);
509 EXPECT_EQ(kUniform1Type, info->type);
510 EXPECT_EQ(kUniform1RealLocation, info->element_locations[0]);
511 EXPECT_STREQ(kUniform1Name, info->name.c_str());
512 info = program->GetUniformInfo(1);
513 ASSERT_TRUE(info != NULL);
514 EXPECT_EQ(kUniform2Size, info->size);
515 EXPECT_EQ(kUniform2Type, info->type);
516 EXPECT_EQ(kUniform2RealLocation, info->element_locations[0]);
517 EXPECT_STREQ(kUniform2Name, info->name.c_str());
518 info = program->GetUniformInfo(2);
519 // We emulate certain OpenGL drivers by supplying the name without
520 // the array spec. Our implementation should correctly add the required spec.
521 ASSERT_TRUE(info != NULL);
522 EXPECT_EQ(kUniform3Size, info->size);
523 EXPECT_EQ(kUniform3Type, info->type);
524 EXPECT_EQ(kUniform3RealLocation, info->element_locations[0]);
525 EXPECT_STREQ(kUniform3GoodName, info->name.c_str());
526 EXPECT_TRUE(program->GetUniformInfo(kInvalidIndex) == NULL);
529 TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) {
530 static const GLuint kClientProgramId = 124;
531 static const GLuint kServiceProgramId = 457;
532 Program* program = manager_.CreateProgram(
533 kClientProgramId, kServiceProgramId);
534 ASSERT_TRUE(program != NULL);
535 EXPECT_FALSE(program->CanLink());
536 const GLuint kVShaderClientId = 2001;
537 const GLuint kFShaderClientId = 2002;
538 const GLuint kVShaderServiceId = 3001;
539 const GLuint kFShaderServiceId = 3002;
540 Shader* vshader = shader_manager_.CreateShader(
541 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
542 ASSERT_TRUE(vshader != NULL);
543 TestHelper::SetShaderStates(gl_.get(), vshader, true);
544 Shader* fshader = shader_manager_.CreateShader(
545 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
546 ASSERT_TRUE(fshader != NULL);
547 TestHelper::SetShaderStates(gl_.get(), fshader, true);
548 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
549 EXPECT_FALSE(program->CanLink());
550 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
551 EXPECT_TRUE(program->CanLink());
552 program->DetachShader(&shader_manager_, vshader);
553 EXPECT_FALSE(program->CanLink());
554 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
555 EXPECT_TRUE(program->CanLink());
556 program->DetachShader(&shader_manager_, fshader);
557 EXPECT_FALSE(program->CanLink());
558 EXPECT_FALSE(program->AttachShader(&shader_manager_, vshader));
559 EXPECT_FALSE(program->CanLink());
560 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
561 EXPECT_TRUE(program->CanLink());
562 TestHelper::SetShaderStates(gl_.get(), vshader, false);
563 EXPECT_FALSE(program->CanLink());
564 TestHelper::SetShaderStates(gl_.get(), vshader, true);
565 EXPECT_TRUE(program->CanLink());
566 TestHelper::SetShaderStates(gl_.get(), fshader, false);
567 EXPECT_FALSE(program->CanLink());
568 TestHelper::SetShaderStates(gl_.get(), fshader, true);
569 EXPECT_TRUE(program->CanLink());
570 EXPECT_TRUE(program->DetachShader(&shader_manager_, fshader));
571 EXPECT_FALSE(program->DetachShader(&shader_manager_, fshader));
574 TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) {
575 const Program* program = manager_.GetProgram(kClientProgramId);
576 ASSERT_TRUE(program != NULL);
577 // Emulate the situation that uniform3[1] isn't used and optimized out by
578 // a driver, so it's location is -1.
579 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
580 program->GetUniformInfo(2));
581 ASSERT_TRUE(uniform != NULL && kUniform3Size == 2);
582 EXPECT_EQ(kUniform3Size, uniform->size);
583 uniform->element_locations[1] = -1;
584 EXPECT_EQ(kUniform1FakeLocation,
585 program->GetUniformFakeLocation(kUniform1Name));
586 EXPECT_EQ(kUniform2FakeLocation,
587 program->GetUniformFakeLocation(kUniform2Name));
588 EXPECT_EQ(kUniform3FakeLocation,
589 program->GetUniformFakeLocation(kUniform3BadName));
590 // Check we can get uniform2 as "uniform2" even though the name is
591 // "uniform2[0]"
592 EXPECT_EQ(kUniform2FakeLocation,
593 program->GetUniformFakeLocation("uniform2"));
594 // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
595 // returning "uniform3"
596 EXPECT_EQ(kUniform3FakeLocation,
597 program->GetUniformFakeLocation(kUniform3GoodName));
598 // Check that we can get the locations of the array elements > 1
599 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 1),
600 program->GetUniformFakeLocation("uniform2[1]"));
601 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2),
602 program->GetUniformFakeLocation("uniform2[2]"));
603 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]"));
604 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[1]"));
605 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]"));
608 TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) {
609 const GLint kInvalidLocation = 1234;
610 const Program::UniformInfo* info;
611 const Program* program = manager_.GetProgram(kClientProgramId);
612 GLint real_location = -1;
613 GLint array_index = -1;
614 ASSERT_TRUE(program != NULL);
615 info = program->GetUniformInfoByFakeLocation(
616 kUniform2FakeLocation, &real_location, &array_index);
617 EXPECT_EQ(kUniform2RealLocation, real_location);
618 EXPECT_EQ(0, array_index);
619 ASSERT_TRUE(info != NULL);
620 EXPECT_EQ(kUniform2Type, info->type);
621 real_location = -1;
622 array_index = -1;
623 info = program->GetUniformInfoByFakeLocation(
624 kInvalidLocation, &real_location, &array_index);
625 EXPECT_TRUE(info == NULL);
626 EXPECT_EQ(-1, real_location);
627 EXPECT_EQ(-1, array_index);
628 GLint loc = program->GetUniformFakeLocation("uniform2[2]");
629 info = program->GetUniformInfoByFakeLocation(
630 loc, &real_location, &array_index);
631 ASSERT_TRUE(info != NULL);
632 EXPECT_EQ(kUniform2RealLocation + 2 * 2, real_location);
633 EXPECT_EQ(2, array_index);
636 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
637 // that start with "gl_". Our implementation catches these and does not allow
638 // them back to client.
639 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
640 static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
641 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
642 { kUniform1Name,
643 kUniform1Size,
644 kUniform1Type,
645 kUniform1FakeLocation,
646 kUniform1RealLocation,
647 kUniform1DesiredLocation,
648 kUniform1Name,
650 { kUniform2Name,
651 kUniform2Size,
652 kUniform2Type,
653 kUniform2FakeLocation,
654 kUniform2RealLocation,
655 kUniform2DesiredLocation,
656 kUniform2Name,
658 { kUniform3BadName,
659 kUniform3Size,
660 kUniform3Type,
661 kUniform3FakeLocation,
662 kUniform3RealLocation,
663 kUniform3DesiredLocation,
664 kUniform3GoodName,
667 const size_t kNumUniforms = arraysize(kUniforms);
668 static const GLuint kClientProgramId = 1234;
669 static const GLuint kServiceProgramId = 5679;
670 const GLuint kVShaderClientId = 2001;
671 const GLuint kFShaderClientId = 2002;
672 const GLuint kVShaderServiceId = 3001;
673 const GLuint kFShaderServiceId = 3002;
674 SetupShader(
675 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
676 Shader* vshader = shader_manager_.CreateShader(
677 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
678 ASSERT_TRUE(vshader != NULL);
679 TestHelper::SetShaderStates(gl_.get(), vshader, true);
680 Shader* fshader = shader_manager_.CreateShader(
681 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
682 ASSERT_TRUE(fshader != NULL);
683 TestHelper::SetShaderStates(gl_.get(), fshader, true);
684 Program* program =
685 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
686 ASSERT_TRUE(program != NULL);
687 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
688 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
689 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
690 base::Bind(&ShaderCacheCb));
691 GLint value = 0;
692 program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
693 EXPECT_EQ(3, value);
694 // Check that we skipped the "gl_" uniform.
695 program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
696 EXPECT_EQ(2, value);
697 // Check that our max length adds room for the array spec and is not as long
698 // as the "gl_" uniform we skipped.
699 // +4u is to account for "gl_" and NULL terminator.
700 program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
701 EXPECT_EQ(strlen(kUniform3BadName) + 4u, static_cast<size_t>(value));
704 // Test the bug comparing similar array names is fixed.
705 TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
706 static const char* kUniform2Name = "u_nameLong[0]";
707 static const char* kUniform3Name = "u_name[0]";
708 static const GLint kUniform2Size = 2;
709 static const GLint kUniform3Size = 2;
710 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
711 { kUniform1Name,
712 kUniform1Size,
713 kUniform1Type,
714 kUniform1FakeLocation,
715 kUniform1RealLocation,
716 kUniform1DesiredLocation,
717 kUniform1Name,
719 { kUniform2Name,
720 kUniform2Size,
721 kUniform2Type,
722 kUniform2FakeLocation,
723 kUniform2RealLocation,
724 kUniform2DesiredLocation,
725 kUniform2Name,
727 { kUniform3Name,
728 kUniform3Size,
729 kUniform3Type,
730 kUniform3FakeLocation,
731 kUniform3RealLocation,
732 kUniform3DesiredLocation,
733 kUniform3Name,
736 const size_t kNumUniforms = arraysize(kUniforms);
737 static const GLuint kClientProgramId = 1234;
738 static const GLuint kServiceProgramId = 5679;
739 const GLuint kVShaderClientId = 2001;
740 const GLuint kFShaderClientId = 2002;
741 const GLuint kVShaderServiceId = 3001;
742 const GLuint kFShaderServiceId = 3002;
743 SetupShader(
744 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
745 Shader* vshader = shader_manager_.CreateShader(
746 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
747 ASSERT_TRUE(vshader != NULL);
748 TestHelper::SetShaderStates(gl_.get(), vshader, true);
749 Shader* fshader = shader_manager_.CreateShader(
750 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
751 ASSERT_TRUE(fshader != NULL);
752 TestHelper::SetShaderStates(gl_.get(), fshader, true);
753 Program* program =
754 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
755 ASSERT_TRUE(program != NULL);
756 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
757 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
758 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
759 base::Bind(&ShaderCacheCb));
761 // Check that we get the correct locations.
762 EXPECT_EQ(kUniform2FakeLocation,
763 program->GetUniformFakeLocation(kUniform2Name));
764 EXPECT_EQ(kUniform3FakeLocation,
765 program->GetUniformFakeLocation(kUniform3Name));
768 // Some GL drivers incorrectly return the wrong type. For example they return
769 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
770 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
771 static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
772 static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
773 static GLenum kUniform2BadType = GL_FLOAT_VEC3;
774 static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
775 ShaderTranslator::VariableMap attrib_map;
776 ShaderTranslator::VariableMap uniform_map;
777 ShaderTranslator::VariableMap varying_map;
778 attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
779 kAttrib1Type, kAttrib1Size, kAttrib1Precision,
780 kAttribStaticUse, kAttrib1Name);
781 attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
782 kAttrib2GoodType, kAttrib2Size, kAttrib2Precision,
783 kAttribStaticUse, kAttrib2Name);
784 attrib_map[kAttrib3Name] = ShaderTranslatorInterface::VariableInfo(
785 kAttrib3Type, kAttrib3Size, kAttrib3Precision,
786 kAttribStaticUse, kAttrib3Name);
787 uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
788 kUniform1Type, kUniform1Size, kUniform1Precision,
789 kUniform1StaticUse, kUniform1Name);
790 uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
791 kUniform2GoodType, kUniform2Size, kUniform2Precision,
792 kUniform2StaticUse, kUniform2Name);
793 uniform_map[kUniform3GoodName] = ShaderTranslatorInterface::VariableInfo(
794 kUniform3Type, kUniform3Size, kUniform3Precision,
795 kUniform3StaticUse, kUniform3GoodName);
796 const GLuint kVShaderClientId = 2001;
797 const GLuint kFShaderClientId = 2002;
798 const GLuint kVShaderServiceId = 3001;
799 const GLuint kFShaderServiceId = 3002;
800 Shader* vshader = shader_manager_.CreateShader(
801 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
802 ASSERT_TRUE(vshader != NULL);
803 TestHelper::SetShaderStates(
804 gl_.get(), vshader, true, NULL, NULL,
805 &attrib_map, &uniform_map, &varying_map, NULL);
806 Shader* fshader = shader_manager_.CreateShader(
807 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
808 ASSERT_TRUE(fshader != NULL);
809 TestHelper::SetShaderStates(
810 gl_.get(), fshader, true, NULL, NULL,
811 &attrib_map, &uniform_map, &varying_map, NULL);
812 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
813 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
814 { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
815 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
817 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
818 { kUniform1Name,
819 kUniform1Size,
820 kUniform1Type,
821 kUniform1FakeLocation,
822 kUniform1RealLocation,
823 kUniform1DesiredLocation,
824 kUniform1Name,
826 { kUniform2Name,
827 kUniform2Size,
828 kUniform2BadType,
829 kUniform2FakeLocation,
830 kUniform2RealLocation,
831 kUniform2DesiredLocation,
832 kUniform2Name,
834 { kUniform3BadName,
835 kUniform3Size,
836 kUniform3Type,
837 kUniform3FakeLocation,
838 kUniform3RealLocation,
839 kUniform3DesiredLocation,
840 kUniform3GoodName,
843 const size_t kNumAttribs= arraysize(kAttribs);
844 const size_t kNumUniforms = arraysize(kUniforms);
845 static const GLuint kClientProgramId = 1234;
846 static const GLuint kServiceProgramId = 5679;
847 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
848 kServiceProgramId);
849 Program* program = manager_.CreateProgram(
850 kClientProgramId, kServiceProgramId);
851 ASSERT_TRUE(program!= NULL);
852 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
853 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
854 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
855 base::Bind(&ShaderCacheCb));
856 // Check that we got the good type, not the bad.
857 // Check Attribs
858 for (unsigned index = 0; index < kNumAttribs; ++index) {
859 const Program::VertexAttrib* attrib_info =
860 program->GetAttribInfo(index);
861 ASSERT_TRUE(attrib_info != NULL);
862 ShaderTranslator::VariableMap::const_iterator it = attrib_map.find(
863 attrib_info->name);
864 ASSERT_TRUE(it != attrib_map.end());
865 EXPECT_EQ(it->first, attrib_info->name);
866 EXPECT_EQ(static_cast<GLenum>(it->second.type), attrib_info->type);
867 EXPECT_EQ(it->second.size, attrib_info->size);
868 EXPECT_EQ(it->second.name, attrib_info->name);
870 // Check Uniforms
871 for (unsigned index = 0; index < kNumUniforms; ++index) {
872 const Program::UniformInfo* uniform_info =
873 program->GetUniformInfo(index);
874 ASSERT_TRUE(uniform_info != NULL);
875 ShaderTranslator::VariableMap::const_iterator it = uniform_map.find(
876 uniform_info->name);
877 ASSERT_TRUE(it != uniform_map.end());
878 EXPECT_EQ(it->first, uniform_info->name);
879 EXPECT_EQ(static_cast<GLenum>(it->second.type), uniform_info->type);
880 EXPECT_EQ(it->second.size, uniform_info->size);
881 EXPECT_EQ(it->second.name, uniform_info->name);
885 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
886 static const GLuint kClientProgramId = 124;
887 static const GLuint kServiceProgramId = 457;
888 Program* program = manager_.CreateProgram(
889 kClientProgramId, kServiceProgramId);
890 ASSERT_TRUE(program != NULL);
891 EXPECT_FALSE(program->CanLink());
892 const GLuint kVShaderClientId = 2001;
893 const GLuint kFShaderClientId = 2002;
894 const GLuint kVShaderServiceId = 3001;
895 const GLuint kFShaderServiceId = 3002;
896 Shader* vshader = shader_manager_.CreateShader(
897 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
898 ASSERT_TRUE(vshader != NULL);
899 TestHelper::SetShaderStates(gl_.get(), vshader, true);
900 Shader* fshader = shader_manager_.CreateShader(
901 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
902 ASSERT_TRUE(fshader != NULL);
903 TestHelper::SetShaderStates(gl_.get(), fshader, true);
904 EXPECT_FALSE(vshader->InUse());
905 EXPECT_FALSE(fshader->InUse());
906 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
907 EXPECT_TRUE(vshader->InUse());
908 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
909 EXPECT_TRUE(fshader->InUse());
910 EXPECT_TRUE(program->CanLink());
911 EXPECT_FALSE(program->InUse());
912 EXPECT_FALSE(program->IsDeleted());
913 manager_.UseProgram(program);
914 EXPECT_TRUE(program->InUse());
915 manager_.UseProgram(program);
916 EXPECT_TRUE(program->InUse());
917 manager_.MarkAsDeleted(&shader_manager_, program);
918 EXPECT_TRUE(program->IsDeleted());
919 Program* info2 = manager_.GetProgram(kClientProgramId);
920 EXPECT_EQ(program, info2);
921 manager_.UnuseProgram(&shader_manager_, program);
922 EXPECT_TRUE(program->InUse());
923 // this should delete the info.
924 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
925 .Times(1)
926 .RetiresOnSaturation();
927 manager_.UnuseProgram(&shader_manager_, program);
928 info2 = manager_.GetProgram(kClientProgramId);
929 EXPECT_TRUE(info2 == NULL);
930 EXPECT_FALSE(vshader->InUse());
931 EXPECT_FALSE(fshader->InUse());
934 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
935 static const GLuint kClientProgramId = 124;
936 static const GLuint kServiceProgramId = 457;
937 Program* program = manager_.CreateProgram(
938 kClientProgramId, kServiceProgramId);
939 ASSERT_TRUE(program != NULL);
940 EXPECT_FALSE(program->CanLink());
941 const GLuint kVShaderClientId = 2001;
942 const GLuint kFShaderClientId = 2002;
943 const GLuint kVShaderServiceId = 3001;
944 const GLuint kFShaderServiceId = 3002;
945 Shader* vshader = shader_manager_.CreateShader(
946 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
947 ASSERT_TRUE(vshader != NULL);
948 TestHelper::SetShaderStates(gl_.get(), vshader, true);
949 Shader* fshader = shader_manager_.CreateShader(
950 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
951 ASSERT_TRUE(fshader != NULL);
952 TestHelper::SetShaderStates(gl_.get(), fshader, true);
953 EXPECT_FALSE(vshader->InUse());
954 EXPECT_FALSE(fshader->InUse());
955 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
956 EXPECT_TRUE(vshader->InUse());
957 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
958 EXPECT_TRUE(fshader->InUse());
959 EXPECT_TRUE(program->CanLink());
960 EXPECT_FALSE(program->InUse());
961 EXPECT_FALSE(program->IsDeleted());
962 manager_.UseProgram(program);
963 EXPECT_TRUE(program->InUse());
964 manager_.UseProgram(program);
965 EXPECT_TRUE(program->InUse());
966 manager_.UnuseProgram(&shader_manager_, program);
967 EXPECT_TRUE(program->InUse());
968 manager_.UnuseProgram(&shader_manager_, program);
969 EXPECT_FALSE(program->InUse());
970 Program* info2 = manager_.GetProgram(kClientProgramId);
971 EXPECT_EQ(program, info2);
972 // this should delete the program.
973 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
974 .Times(1)
975 .RetiresOnSaturation();
976 manager_.MarkAsDeleted(&shader_manager_, program);
977 info2 = manager_.GetProgram(kClientProgramId);
978 EXPECT_TRUE(info2 == NULL);
979 EXPECT_FALSE(vshader->InUse());
980 EXPECT_FALSE(fshader->InUse());
983 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
984 CommonDecoder::Bucket bucket;
985 const Program* program = manager_.GetProgram(kClientProgramId);
986 ASSERT_TRUE(program != NULL);
987 program->GetProgramInfo(&manager_, &bucket);
988 ProgramInfoHeader* header =
989 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
990 ASSERT_TRUE(header != NULL);
991 EXPECT_EQ(1u, header->link_status);
992 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
993 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
994 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
995 sizeof(*header),
996 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
997 ASSERT_TRUE(inputs != NULL);
998 const ProgramInput* input = inputs;
999 // TODO(gman): Don't assume these are in order.
1000 for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
1001 const AttribInfo& expected = kAttribs[ii];
1002 EXPECT_EQ(expected.size, input->size);
1003 EXPECT_EQ(expected.type, input->type);
1004 const int32* location = bucket.GetDataAs<const int32*>(
1005 input->location_offset, sizeof(int32));
1006 ASSERT_TRUE(location != NULL);
1007 EXPECT_EQ(expected.location, *location);
1008 const char* name_buf = bucket.GetDataAs<const char*>(
1009 input->name_offset, input->name_length);
1010 ASSERT_TRUE(name_buf != NULL);
1011 std::string name(name_buf, input->name_length);
1012 EXPECT_STREQ(expected.name, name.c_str());
1013 ++input;
1015 // TODO(gman): Don't assume these are in order.
1016 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1017 const UniformInfo& expected = kUniforms[ii];
1018 EXPECT_EQ(expected.size, input->size);
1019 EXPECT_EQ(expected.type, input->type);
1020 const int32* locations = bucket.GetDataAs<const int32*>(
1021 input->location_offset, sizeof(int32) * input->size);
1022 ASSERT_TRUE(locations != NULL);
1023 for (int32 jj = 0; jj < input->size; ++jj) {
1024 EXPECT_EQ(
1025 ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1026 locations[jj]);
1028 const char* name_buf = bucket.GetDataAs<const char*>(
1029 input->name_offset, input->name_length);
1030 ASSERT_TRUE(name_buf != NULL);
1031 std::string name(name_buf, input->name_length);
1032 EXPECT_STREQ(expected.good_name, name.c_str());
1033 ++input;
1035 EXPECT_EQ(header->num_attribs + header->num_uniforms,
1036 static_cast<uint32>(input - inputs));
1039 // Some drivers optimize out unused uniform array elements, so their
1040 // location would be -1.
1041 TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
1042 CommonDecoder::Bucket bucket;
1043 const Program* program = manager_.GetProgram(kClientProgramId);
1044 ASSERT_TRUE(program != NULL);
1045 // Emulate the situation that only the first element has a valid location.
1046 // TODO(zmo): Don't assume these are in order.
1047 for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
1048 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
1049 program->GetUniformInfo(ii));
1050 ASSERT_TRUE(uniform != NULL);
1051 EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
1052 uniform->element_locations.size());
1053 for (GLsizei jj = 1; jj < uniform->size; ++jj)
1054 uniform->element_locations[jj] = -1;
1056 program->GetProgramInfo(&manager_, &bucket);
1057 ProgramInfoHeader* header =
1058 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1059 ASSERT_TRUE(header != NULL);
1060 EXPECT_EQ(1u, header->link_status);
1061 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1062 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1063 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1064 sizeof(*header),
1065 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1066 ASSERT_TRUE(inputs != NULL);
1067 const ProgramInput* input = inputs + header->num_attribs;
1068 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1069 const UniformInfo& expected = kUniforms[ii];
1070 EXPECT_EQ(expected.size, input->size);
1071 const int32* locations = bucket.GetDataAs<const int32*>(
1072 input->location_offset, sizeof(int32) * input->size);
1073 ASSERT_TRUE(locations != NULL);
1074 EXPECT_EQ(
1075 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1076 locations[0]);
1077 for (int32 jj = 1; jj < input->size; ++jj)
1078 EXPECT_EQ(-1, locations[jj]);
1079 ++input;
1083 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1084 // Set up shader
1085 const GLuint kVShaderClientId = 1;
1086 const GLuint kVShaderServiceId = 11;
1087 const GLuint kFShaderClientId = 2;
1088 const GLuint kFShaderServiceId = 12;
1089 ShaderTranslator::VariableMap attrib_map;
1090 for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
1091 attrib_map[kAttribs[ii].name] = ShaderTranslatorInterface::VariableInfo(
1092 kAttribs[ii].type,
1093 kAttribs[ii].size,
1094 SH_PRECISION_MEDIUMP,
1095 kAttribStaticUse,
1096 kAttribs[ii].name);
1098 // Check we can create shader.
1099 Shader* vshader = shader_manager_.CreateShader(
1100 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1101 Shader* fshader = shader_manager_.CreateShader(
1102 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1103 // Check shader got created.
1104 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1105 // Set Status
1106 TestHelper::SetShaderStates(
1107 gl_.get(), vshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1108 // Check attrib infos got copied.
1109 for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
1110 it != attrib_map.end(); ++it) {
1111 const Shader::VariableInfo* variable_info =
1112 vshader->GetAttribInfo(it->first);
1113 ASSERT_TRUE(variable_info != NULL);
1114 EXPECT_EQ(it->second.type, variable_info->type);
1115 EXPECT_EQ(it->second.size, variable_info->size);
1116 EXPECT_EQ(it->second.precision, variable_info->precision);
1117 EXPECT_EQ(it->second.static_use, variable_info->static_use);
1118 EXPECT_EQ(it->second.name, variable_info->name);
1120 TestHelper::SetShaderStates(
1121 gl_.get(), fshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1123 // Set up program
1124 const GLuint kClientProgramId = 6666;
1125 const GLuint kServiceProgramId = 8888;
1126 Program* program =
1127 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1128 ASSERT_TRUE(program != NULL);
1129 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1130 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1132 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1133 EXPECT_TRUE(LinkAsExpected(program, true));
1135 program->SetAttribLocationBinding(kAttrib1Name, 0);
1136 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1137 EXPECT_TRUE(LinkAsExpected(program, true));
1139 program->SetAttribLocationBinding("xxx", 0);
1140 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1141 EXPECT_TRUE(LinkAsExpected(program, true));
1143 program->SetAttribLocationBinding(kAttrib2Name, 1);
1144 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1145 EXPECT_TRUE(LinkAsExpected(program, true));
1147 program->SetAttribLocationBinding(kAttrib2Name, 0);
1148 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1149 EXPECT_TRUE(LinkAsExpected(program, false));
1152 TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
1153 // Set up shader
1154 const GLuint kVShaderClientId = 1;
1155 const GLuint kVShaderServiceId = 11;
1156 const GLuint kFShaderClientId = 2;
1157 const GLuint kFShaderServiceId = 12;
1159 ShaderTranslator::VariableMap vertex_uniform_map;
1160 vertex_uniform_map["a"] = ShaderTranslator::VariableInfo(
1161 1, 3, SH_PRECISION_MEDIUMP, 1, "a");
1162 ShaderTranslator::VariableMap frag_uniform_map;
1163 frag_uniform_map["a"] = ShaderTranslator::VariableInfo(
1164 1, 3, SH_PRECISION_LOWP, 1, "a");
1166 // Check we can create shader.
1167 Shader* vshader = shader_manager_.CreateShader(
1168 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1169 Shader* fshader = shader_manager_.CreateShader(
1170 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1171 // Check shader got created.
1172 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1173 // Set Status
1174 TestHelper::SetShaderStates(
1175 gl_.get(), vshader, true, NULL, NULL, NULL,
1176 &vertex_uniform_map, NULL, NULL);
1177 TestHelper::SetShaderStates(
1178 gl_.get(), fshader, true, NULL, NULL, NULL,
1179 &frag_uniform_map, NULL, NULL);
1181 // Set up program
1182 const GLuint kClientProgramId = 6666;
1183 const GLuint kServiceProgramId = 8888;
1184 Program* program =
1185 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1186 ASSERT_TRUE(program != NULL);
1187 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1188 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1190 std::string conflicting_name;
1192 EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1193 EXPECT_EQ("a", conflicting_name);
1194 EXPECT_TRUE(LinkAsExpected(program, false));
1197 // If a varying has different type in the vertex and fragment
1198 // shader, linking should fail.
1199 TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
1200 const VarInfo kVertexVarying =
1201 { GL_FLOAT_VEC3, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1202 const VarInfo kFragmentVarying =
1203 { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1204 Program* program = SetupShaderVariableTest(
1205 &kVertexVarying, 1, &kFragmentVarying, 1);
1207 std::string conflicting_name;
1209 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1210 EXPECT_EQ("a", conflicting_name);
1211 EXPECT_TRUE(LinkAsExpected(program, false));
1214 // If a varying has different array size in the vertex and fragment
1215 // shader, linking should fail.
1216 TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
1217 const VarInfo kVertexVarying =
1218 { GL_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1219 const VarInfo kFragmentVarying =
1220 { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1221 Program* program = SetupShaderVariableTest(
1222 &kVertexVarying, 1, &kFragmentVarying, 1);
1224 std::string conflicting_name;
1226 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1227 EXPECT_EQ("a", conflicting_name);
1228 EXPECT_TRUE(LinkAsExpected(program, false));
1231 // If a varying has different precision in the vertex and fragment
1232 // shader, linking should succeed.
1233 TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
1234 const VarInfo kVertexVarying =
1235 { GL_FLOAT, 2, SH_PRECISION_HIGHP, 1, "a", kVarVarying };
1236 const VarInfo kFragmentVarying =
1237 { GL_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1238 Program* program = SetupShaderVariableTest(
1239 &kVertexVarying, 1, &kFragmentVarying, 1);
1241 std::string conflicting_name;
1243 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1244 EXPECT_TRUE(conflicting_name.empty());
1245 EXPECT_TRUE(LinkAsExpected(program, true));
1248 // If a varying is statically used in fragment shader but not
1249 // declared in vertex shader, link should fail.
1250 TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
1251 const VarInfo kFragmentVarying =
1252 { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1253 Program* program = SetupShaderVariableTest(
1254 NULL, 0, &kFragmentVarying, 1);
1256 std::string conflicting_name;
1258 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1259 EXPECT_EQ("a", conflicting_name);
1260 EXPECT_TRUE(LinkAsExpected(program, false));
1263 // If a varying is declared but not statically used in fragment
1264 // shader, even if it's not declared in vertex shader, link should
1265 // succeed.
1266 TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
1267 const VarInfo kFragmentVarying =
1268 { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying };
1269 Program* program = SetupShaderVariableTest(
1270 NULL, 0, &kFragmentVarying, 1);
1272 std::string conflicting_name;
1274 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1275 EXPECT_TRUE(conflicting_name.empty());
1276 EXPECT_TRUE(LinkAsExpected(program, true));
1279 // Uniforms and attributes are both global variables, thus sharing
1280 // the same namespace. Any name conflicts should cause link
1281 // failure.
1282 TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
1283 const VarInfo kVertexAttribute =
1284 { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarAttribute };
1285 const VarInfo kFragmentUniform =
1286 { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarUniform };
1287 Program* program = SetupShaderVariableTest(
1288 &kVertexAttribute, 1, &kFragmentUniform, 1);
1290 std::string conflicting_name;
1292 EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1293 EXPECT_EQ("a", conflicting_name);
1294 EXPECT_TRUE(LinkAsExpected(program, false));
1297 // Varyings go over 8 rows.
1298 TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
1299 const VarInfo kVertexVaryings[] = {
1300 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1301 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1303 const VarInfo kFragmentVaryings[] = {
1304 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1305 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1307 Program* program = SetupShaderVariableTest(
1308 kVertexVaryings, 2, kFragmentVaryings, 2);
1310 EXPECT_FALSE(
1311 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1312 EXPECT_TRUE(LinkAsExpected(program, false));
1315 // Varyings go over 8 rows but some are inactive
1316 TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
1317 const VarInfo kVertexVaryings[] = {
1318 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1319 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1321 const VarInfo kFragmentVaryings[] = {
1322 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
1323 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1325 Program* program = SetupShaderVariableTest(
1326 kVertexVaryings, 2, kFragmentVaryings, 2);
1328 EXPECT_TRUE(
1329 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1330 EXPECT_TRUE(LinkAsExpected(program, true));
1333 // Varyings go over 8 rows but some are inactive.
1334 // However, we still fail the check if kCountAll option is used.
1335 TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
1336 const VarInfo kVertexVaryings[] = {
1337 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1338 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1340 const VarInfo kFragmentVaryings[] = {
1341 { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
1342 { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1344 Program* program = SetupShaderVariableTest(
1345 kVertexVaryings, 2, kFragmentVaryings, 2);
1347 EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1350 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
1351 const GLuint kVShaderClientId = 2001;
1352 const GLuint kFShaderClientId = 2002;
1353 const GLuint kVShaderServiceId = 3001;
1354 const GLuint kFShaderServiceId = 3002;
1355 Shader* vshader = shader_manager_.CreateShader(
1356 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1357 ASSERT_TRUE(vshader != NULL);
1358 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1359 Shader* fshader = shader_manager_.CreateShader(
1360 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1361 ASSERT_TRUE(fshader != NULL);
1362 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1363 static const GLuint kClientProgramId = 1234;
1364 static const GLuint kServiceProgramId = 5679;
1365 Program* program = manager_.CreateProgram(
1366 kClientProgramId, kServiceProgramId);
1367 ASSERT_TRUE(program != NULL);
1368 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1369 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1371 static const GLenum kSamplerTypes[] = {
1372 GL_SAMPLER_2D,
1373 GL_SAMPLER_CUBE,
1374 GL_SAMPLER_EXTERNAL_OES,
1375 GL_SAMPLER_3D_OES,
1376 GL_SAMPLER_2D_RECT_ARB,
1378 const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
1379 for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
1380 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1381 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1382 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1383 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1385 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1386 { kUniform1Name,
1387 kUniform1Size,
1388 kUniform1Type,
1389 kUniform1FakeLocation,
1390 kUniform1RealLocation,
1391 kUniform1DesiredLocation,
1392 kUniform1Name,
1394 { kUniform2Name,
1395 kUniform2Size,
1396 kSamplerTypes[ii],
1397 kUniform2FakeLocation,
1398 kUniform2RealLocation,
1399 kUniform2DesiredLocation,
1400 kUniform2Name,
1402 { kUniform3BadName,
1403 kUniform3Size,
1404 kUniform3Type,
1405 kUniform3FakeLocation,
1406 kUniform3RealLocation,
1407 kUniform3DesiredLocation,
1408 kUniform3GoodName,
1411 const size_t kNumAttribs = arraysize(kAttribs);
1412 const size_t kNumUniforms = arraysize(kUniforms);
1413 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1414 kServiceProgramId);
1415 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
1416 base::Bind(&ShaderCacheCb));
1417 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
1418 manager_.ClearUniforms(program);
1422 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
1423 const GLuint kVShaderClientId = 2001;
1424 const GLuint kFShaderClientId = 2002;
1425 const GLuint kVShaderServiceId = 3001;
1426 const GLuint kFShaderServiceId = 3002;
1428 const GLint kUniform1DesiredLocation = 10;
1429 const GLint kUniform2DesiredLocation = -1;
1430 const GLint kUniform3DesiredLocation = 5;
1432 Shader* vshader = shader_manager_.CreateShader(
1433 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1434 ASSERT_TRUE(vshader != NULL);
1435 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1436 Shader* fshader = shader_manager_.CreateShader(
1437 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1438 ASSERT_TRUE(fshader != NULL);
1439 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1440 static const GLuint kClientProgramId = 1234;
1441 static const GLuint kServiceProgramId = 5679;
1442 Program* program = manager_.CreateProgram(
1443 kClientProgramId, kServiceProgramId);
1444 ASSERT_TRUE(program != NULL);
1445 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1446 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1447 EXPECT_TRUE(program->SetUniformLocationBinding(
1448 kUniform1Name, kUniform1DesiredLocation));
1449 EXPECT_TRUE(program->SetUniformLocationBinding(
1450 kUniform3BadName, kUniform3DesiredLocation));
1452 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1453 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1454 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1455 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1457 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1458 { kUniform1Name,
1459 kUniform1Size,
1460 kUniform1Type,
1461 kUniform1FakeLocation,
1462 kUniform1RealLocation,
1463 kUniform1DesiredLocation,
1464 kUniform1Name,
1466 { kUniform2Name,
1467 kUniform2Size,
1468 kUniform2Type,
1469 kUniform2FakeLocation,
1470 kUniform2RealLocation,
1471 kUniform2DesiredLocation,
1472 kUniform2Name,
1474 { kUniform3BadName,
1475 kUniform3Size,
1476 kUniform3Type,
1477 kUniform3FakeLocation,
1478 kUniform3RealLocation,
1479 kUniform3DesiredLocation,
1480 kUniform3GoodName,
1484 const size_t kNumAttribs = arraysize(kAttribs);
1485 const size_t kNumUniforms = arraysize(kUniforms);
1486 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1487 kServiceProgramId);
1488 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
1489 base::Bind(&ShaderCacheCb));
1491 EXPECT_EQ(kUniform1DesiredLocation,
1492 program->GetUniformFakeLocation(kUniform1Name));
1493 EXPECT_EQ(kUniform3DesiredLocation,
1494 program->GetUniformFakeLocation(kUniform3BadName));
1495 EXPECT_EQ(kUniform3DesiredLocation,
1496 program->GetUniformFakeLocation(kUniform3GoodName));
1499 class ProgramManagerWithCacheTest : public GpuServiceTest {
1500 public:
1501 static const GLuint kClientProgramId = 1;
1502 static const GLuint kServiceProgramId = 10;
1503 static const GLuint kVertexShaderClientId = 2;
1504 static const GLuint kFragmentShaderClientId = 20;
1505 static const GLuint kVertexShaderServiceId = 3;
1506 static const GLuint kFragmentShaderServiceId = 30;
1508 ProgramManagerWithCacheTest()
1509 : cache_(new MockProgramCache()),
1510 manager_(cache_.get(), kMaxVaryingVectors),
1511 vertex_shader_(NULL),
1512 fragment_shader_(NULL),
1513 program_(NULL) {
1515 virtual ~ProgramManagerWithCacheTest() {
1516 manager_.Destroy(false);
1517 shader_manager_.Destroy(false);
1520 protected:
1521 virtual void SetUp() {
1522 GpuServiceTest::SetUp();
1524 vertex_shader_ = shader_manager_.CreateShader(
1525 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
1526 fragment_shader_ = shader_manager_.CreateShader(
1527 kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
1528 ASSERT_TRUE(vertex_shader_ != NULL);
1529 ASSERT_TRUE(fragment_shader_ != NULL);
1530 vertex_shader_->set_source("lka asjf bjajsdfj");
1531 fragment_shader_->set_source("lka asjf a fasgag 3rdsf3 bjajsdfj");
1533 program_ = manager_.CreateProgram(
1534 kClientProgramId, kServiceProgramId);
1535 ASSERT_TRUE(program_ != NULL);
1537 program_->AttachShader(&shader_manager_, vertex_shader_);
1538 program_->AttachShader(&shader_manager_, fragment_shader_);
1541 void SetShadersCompiled() {
1542 TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
1543 TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
1546 void SetProgramCached() {
1547 cache_->LinkedProgramCacheSuccess(
1548 vertex_shader_->source(),
1549 NULL,
1550 fragment_shader_->source(),
1551 NULL,
1552 &program_->bind_attrib_location_map());
1555 void SetExpectationsForProgramCached() {
1556 SetExpectationsForProgramCached(program_,
1557 vertex_shader_,
1558 fragment_shader_);
1561 void SetExpectationsForProgramCached(
1562 Program* program,
1563 Shader* vertex_shader,
1564 Shader* fragment_shader) {
1565 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1566 program->service_id(),
1567 vertex_shader,
1568 NULL,
1569 fragment_shader,
1570 NULL,
1571 &program->bind_attrib_location_map(),
1572 _)).Times(1);
1575 void SetExpectationsForNotCachingProgram() {
1576 SetExpectationsForNotCachingProgram(program_,
1577 vertex_shader_,
1578 fragment_shader_);
1581 void SetExpectationsForNotCachingProgram(
1582 Program* program,
1583 Shader* vertex_shader,
1584 Shader* fragment_shader) {
1585 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1586 program->service_id(),
1587 vertex_shader,
1588 NULL,
1589 fragment_shader,
1590 NULL,
1591 &program->bind_attrib_location_map(),
1592 _)).Times(0);
1595 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
1596 SetExpectationsForProgramLoad(kServiceProgramId,
1597 program_,
1598 vertex_shader_,
1599 fragment_shader_,
1600 result);
1603 void SetExpectationsForProgramLoad(
1604 GLuint service_program_id,
1605 Program* program,
1606 Shader* vertex_shader,
1607 Shader* fragment_shader,
1608 ProgramCache::ProgramLoadResult result) {
1609 EXPECT_CALL(*cache_.get(),
1610 LoadLinkedProgram(service_program_id,
1611 vertex_shader,
1612 NULL,
1613 fragment_shader,
1614 NULL,
1615 &program->bind_attrib_location_map(),
1617 .WillOnce(Return(result));
1620 void SetExpectationsForProgramLoadSuccess() {
1621 SetExpectationsForProgramLoadSuccess(kServiceProgramId);
1624 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
1625 TestHelper::SetupProgramSuccessExpectations(gl_.get(),
1626 NULL,
1628 NULL,
1630 service_program_id);
1633 void SetExpectationsForProgramLink() {
1634 SetExpectationsForProgramLink(kServiceProgramId);
1637 void SetExpectationsForProgramLink(GLuint service_program_id) {
1638 TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
1639 if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
1640 EXPECT_CALL(*gl_.get(),
1641 ProgramParameteri(service_program_id,
1642 PROGRAM_BINARY_RETRIEVABLE_HINT,
1643 GL_TRUE)).Times(1);
1647 void SetExpectationsForSuccessCompile(
1648 const Shader* shader) {
1649 const GLuint shader_id = shader->service_id();
1650 const char* src = shader->source().c_str();
1651 EXPECT_CALL(*gl_.get(),
1652 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
1653 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
1654 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1655 .WillOnce(SetArgumentPointee<2>(GL_TRUE));
1658 void SetExpectationsForNoCompile(const Shader* shader) {
1659 const GLuint shader_id = shader->service_id();
1660 const char* src = shader->source().c_str();
1661 EXPECT_CALL(*gl_.get(),
1662 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
1663 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
1664 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1665 .Times(0);
1668 void SetExpectationsForErrorCompile(const Shader* shader) {
1669 const GLuint shader_id = shader->service_id();
1670 const char* src = shader->source().c_str();
1671 EXPECT_CALL(*gl_.get(),
1672 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
1673 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
1674 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1675 .WillOnce(SetArgumentPointee<2>(GL_FALSE));
1676 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
1677 .WillOnce(SetArgumentPointee<2>(0));
1678 EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
1679 .Times(1);
1682 scoped_ptr<MockProgramCache> cache_;
1683 ProgramManager manager_;
1685 Shader* vertex_shader_;
1686 Shader* fragment_shader_;
1687 Program* program_;
1688 ShaderManager shader_manager_;
1691 // GCC requires these declarations, but MSVC requires they not be present
1692 #ifndef COMPILER_MSVC
1693 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
1694 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
1695 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
1696 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
1697 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
1698 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
1699 #endif
1701 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
1702 SetShadersCompiled();
1703 SetExpectationsForProgramLink();
1704 SetExpectationsForProgramCached();
1705 EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
1706 Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
1709 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
1710 SetShadersCompiled();
1711 SetProgramCached();
1713 SetExpectationsForNoCompile(vertex_shader_);
1714 SetExpectationsForNoCompile(fragment_shader_);
1715 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
1716 SetExpectationsForNotCachingProgram();
1717 SetExpectationsForProgramLoadSuccess();
1719 EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
1720 Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
1723 } // namespace gles2
1724 } // namespace gpu