Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blob6c296e6ad095b850304a7876564a0da61e723d23
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::SetArgPointee;
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) {}
42 uint32 ComputeOffset(const void* start, const void* position) {
43 return static_cast<const uint8*>(position) -
44 static_cast<const uint8*>(start);
47 } // namespace anonymous
49 class ProgramManagerTest : public GpuServiceTest {
50 public:
51 ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
52 ~ProgramManagerTest() override { manager_.Destroy(false); }
54 protected:
55 ProgramManager manager_;
58 TEST_F(ProgramManagerTest, Basic) {
59 const GLuint kClient1Id = 1;
60 const GLuint kService1Id = 11;
61 const GLuint kClient2Id = 2;
62 // Check we can create program.
63 manager_.CreateProgram(kClient1Id, kService1Id);
64 // Check program got created.
65 Program* program1 = manager_.GetProgram(kClient1Id);
66 ASSERT_TRUE(program1 != NULL);
67 GLuint client_id = 0;
68 EXPECT_TRUE(manager_.GetClientId(program1->service_id(), &client_id));
69 EXPECT_EQ(kClient1Id, client_id);
70 // Check we get nothing for a non-existent program.
71 EXPECT_TRUE(manager_.GetProgram(kClient2Id) == NULL);
74 TEST_F(ProgramManagerTest, Destroy) {
75 const GLuint kClient1Id = 1;
76 const GLuint kService1Id = 11;
77 // Check we can create program.
78 Program* program0 = manager_.CreateProgram(kClient1Id, kService1Id);
79 ASSERT_TRUE(program0 != NULL);
80 // Check program got created.
81 Program* program1 = manager_.GetProgram(kClient1Id);
82 ASSERT_EQ(program0, program1);
83 EXPECT_CALL(*gl_, DeleteProgram(kService1Id))
84 .Times(1)
85 .RetiresOnSaturation();
86 manager_.Destroy(true);
87 // Check the resources were released.
88 program1 = manager_.GetProgram(kClient1Id);
89 ASSERT_TRUE(program1 == NULL);
92 TEST_F(ProgramManagerTest, DeleteBug) {
93 ShaderManager shader_manager;
94 const GLuint kClient1Id = 1;
95 const GLuint kClient2Id = 2;
96 const GLuint kService1Id = 11;
97 const GLuint kService2Id = 12;
98 // Check we can create program.
99 scoped_refptr<Program> program1(
100 manager_.CreateProgram(kClient1Id, kService1Id));
101 scoped_refptr<Program> program2(
102 manager_.CreateProgram(kClient2Id, kService2Id));
103 // Check program got created.
104 ASSERT_TRUE(program1.get());
105 ASSERT_TRUE(program2.get());
106 manager_.UseProgram(program1.get());
107 manager_.MarkAsDeleted(&shader_manager, program1.get());
108 // Program will be deleted when last ref is released.
109 EXPECT_CALL(*gl_, DeleteProgram(kService2Id))
110 .Times(1)
111 .RetiresOnSaturation();
112 manager_.MarkAsDeleted(&shader_manager, program2.get());
113 EXPECT_TRUE(manager_.IsOwned(program1.get()));
114 EXPECT_FALSE(manager_.IsOwned(program2.get()));
117 TEST_F(ProgramManagerTest, Program) {
118 const GLuint kClient1Id = 1;
119 const GLuint kService1Id = 11;
120 // Check we can create program.
121 Program* program1 = manager_.CreateProgram(
122 kClient1Id, kService1Id);
123 ASSERT_TRUE(program1);
124 EXPECT_EQ(kService1Id, program1->service_id());
125 EXPECT_FALSE(program1->InUse());
126 EXPECT_FALSE(program1->IsValid());
127 EXPECT_FALSE(program1->IsDeleted());
128 EXPECT_FALSE(program1->CanLink());
129 EXPECT_TRUE(program1->log_info() == NULL);
132 class ProgramManagerWithShaderTest : public GpuServiceTest {
133 public:
134 ProgramManagerWithShaderTest()
135 : manager_(NULL, kMaxVaryingVectors), program_(NULL) {
138 ~ProgramManagerWithShaderTest() override {
139 manager_.Destroy(false);
140 shader_manager_.Destroy(false);
143 static const GLint kNumVertexAttribs = 16;
145 static const GLuint kClientProgramId = 123;
146 static const GLuint kServiceProgramId = 456;
147 static const GLuint kVertexShaderClientId = 201;
148 static const GLuint kFragmentShaderClientId = 202;
149 static const GLuint kVertexShaderServiceId = 301;
150 static const GLuint kFragmentShaderServiceId = 302;
152 static const char* kAttrib1Name;
153 static const char* kAttrib2Name;
154 static const char* kAttrib3Name;
155 static const GLint kAttrib1Size = 1;
156 static const GLint kAttrib2Size = 1;
157 static const GLint kAttrib3Size = 1;
158 static const GLenum kAttrib1Precision = GL_MEDIUM_FLOAT;
159 static const GLenum kAttrib2Precision = GL_HIGH_FLOAT;
160 static const GLenum kAttrib3Precision = GL_LOW_FLOAT;
161 static const bool kAttribStaticUse = true;
162 static const GLint kAttrib1Location = 0;
163 static const GLint kAttrib2Location = 1;
164 static const GLint kAttrib3Location = 2;
165 static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
166 static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
167 static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
168 static const GLint kInvalidAttribLocation = 30;
169 static const GLint kBadAttribIndex = kNumVertexAttribs;
171 static const char* kUniform1Name;
172 static const char* kUniform2Name;
173 static const char* kUniform2NameWithArrayIndex;
174 static const char* kUniform3Name;
175 static const char* kUniform3NameWithArrayIndex;
176 static const GLint kUniform1Size = 1;
177 static const GLint kUniform2Size = 3;
178 static const GLint kUniform3Size = 2;
179 static const int kUniform1Precision = GL_LOW_FLOAT;
180 static const int kUniform2Precision = GL_MEDIUM_INT;
181 static const int kUniform3Precision = GL_HIGH_FLOAT;
182 static const int kUniform1StaticUse = 1;
183 static const int kUniform2StaticUse = 1;
184 static const int kUniform3StaticUse = 1;
185 static const GLint kUniform1FakeLocation = 0; // These are hard coded
186 static const GLint kUniform2FakeLocation = 1; // to match
187 static const GLint kUniform3FakeLocation = 2; // ProgramManager.
188 static const GLint kUniform1RealLocation = 11;
189 static const GLint kUniform2RealLocation = 22;
190 static const GLint kUniform3RealLocation = 33;
191 static const GLint kUniform1DesiredLocation = -1;
192 static const GLint kUniform2DesiredLocation = -1;
193 static const GLint kUniform3DesiredLocation = -1;
194 static const GLenum kUniform1Type = GL_FLOAT_VEC4;
195 static const GLenum kUniform2Type = GL_INT_VEC2;
196 static const GLenum kUniform3Type = GL_FLOAT_VEC3;
197 static const GLint kInvalidUniformLocation = 30;
198 static const GLint kBadUniformIndex = 1000;
200 static const size_t kNumAttribs;
201 static const size_t kNumUniforms;
203 protected:
204 typedef TestHelper::AttribInfo AttribInfo;
205 typedef TestHelper::UniformInfo UniformInfo;
207 typedef enum {
208 kVarUniform,
209 kVarVarying,
210 kVarAttribute
211 } VarCategory;
213 typedef struct {
214 GLenum type;
215 GLint size;
216 GLenum precision;
217 bool static_use;
218 std::string name;
219 VarCategory category;
220 } VarInfo;
222 void SetUp() override {
223 // Need to be at leat 3.1 for UniformBlock related GL APIs.
224 GpuServiceTest::SetUpWithGLVersion("3.1", NULL);
226 SetupDefaultShaderExpectations();
228 Shader* vertex_shader = shader_manager_.CreateShader(
229 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
230 Shader* fragment_shader =
231 shader_manager_.CreateShader(
232 kFragmentShaderClientId, kFragmentShaderServiceId,
233 GL_FRAGMENT_SHADER);
234 ASSERT_TRUE(vertex_shader != NULL);
235 ASSERT_TRUE(fragment_shader != NULL);
236 TestHelper::SetShaderStates(gl_.get(), vertex_shader, true);
237 TestHelper::SetShaderStates(gl_.get(), fragment_shader, true);
239 program_ = manager_.CreateProgram(
240 kClientProgramId, kServiceProgramId);
241 ASSERT_TRUE(program_ != NULL);
243 program_->AttachShader(&shader_manager_, vertex_shader);
244 program_->AttachShader(&shader_manager_, fragment_shader);
245 program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
246 base::Bind(&ShaderCacheCb));
249 void SetupShader(AttribInfo* attribs, size_t num_attribs,
250 UniformInfo* uniforms, size_t num_uniforms,
251 GLuint service_id) {
252 TestHelper::SetupShader(
253 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
256 void SetupDefaultShaderExpectations() {
257 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
258 kServiceProgramId);
261 void SetupExpectationsForClearingUniforms(
262 UniformInfo* uniforms, size_t num_uniforms) {
263 TestHelper::SetupExpectationsForClearingUniforms(
264 gl_.get(), uniforms, num_uniforms);
267 // Return true if link status matches expected_link_status
268 bool LinkAsExpected(Program* program,
269 bool expected_link_status) {
270 GLuint service_id = program->service_id();
271 if (expected_link_status) {
272 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
273 service_id);
275 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
276 base::Bind(&ShaderCacheCb));
277 GLint link_status;
278 program->GetProgramiv(GL_LINK_STATUS, &link_status);
279 return (static_cast<bool>(link_status) == expected_link_status);
282 Program* SetupShaderVariableTest(const VarInfo* vertex_variables,
283 size_t vertex_variable_size,
284 const VarInfo* fragment_variables,
285 size_t fragment_variable_size) {
286 // Set up shader
287 const GLuint kVShaderClientId = 1;
288 const GLuint kVShaderServiceId = 11;
289 const GLuint kFShaderClientId = 2;
290 const GLuint kFShaderServiceId = 12;
292 AttributeMap vertex_attrib_map;
293 UniformMap vertex_uniform_map;
294 VaryingMap vertex_varying_map;
295 for (size_t ii = 0; ii < vertex_variable_size; ++ii) {
296 switch (vertex_variables[ii].category) {
297 case kVarAttribute:
298 vertex_attrib_map[vertex_variables[ii].name] =
299 TestHelper::ConstructAttribute(
300 vertex_variables[ii].type,
301 vertex_variables[ii].size,
302 vertex_variables[ii].precision,
303 vertex_variables[ii].static_use,
304 vertex_variables[ii].name);
305 break;
306 case kVarUniform:
307 vertex_uniform_map[vertex_variables[ii].name] =
308 TestHelper::ConstructUniform(
309 vertex_variables[ii].type,
310 vertex_variables[ii].size,
311 vertex_variables[ii].precision,
312 vertex_variables[ii].static_use,
313 vertex_variables[ii].name);
314 break;
315 case kVarVarying:
316 vertex_varying_map[vertex_variables[ii].name] =
317 TestHelper::ConstructVarying(
318 vertex_variables[ii].type,
319 vertex_variables[ii].size,
320 vertex_variables[ii].precision,
321 vertex_variables[ii].static_use,
322 vertex_variables[ii].name);
323 break;
324 default:
325 NOTREACHED();
329 AttributeMap frag_attrib_map;
330 UniformMap frag_uniform_map;
331 VaryingMap frag_varying_map;
332 for (size_t ii = 0; ii < fragment_variable_size; ++ii) {
333 switch (fragment_variables[ii].category) {
334 case kVarAttribute:
335 frag_attrib_map[fragment_variables[ii].name] =
336 TestHelper::ConstructAttribute(
337 fragment_variables[ii].type,
338 fragment_variables[ii].size,
339 fragment_variables[ii].precision,
340 fragment_variables[ii].static_use,
341 fragment_variables[ii].name);
342 break;
343 case kVarUniform:
344 frag_uniform_map[fragment_variables[ii].name] =
345 TestHelper::ConstructUniform(
346 fragment_variables[ii].type,
347 fragment_variables[ii].size,
348 fragment_variables[ii].precision,
349 fragment_variables[ii].static_use,
350 fragment_variables[ii].name);
351 break;
352 case kVarVarying:
353 frag_varying_map[fragment_variables[ii].name] =
354 TestHelper::ConstructVarying(
355 fragment_variables[ii].type,
356 fragment_variables[ii].size,
357 fragment_variables[ii].precision,
358 fragment_variables[ii].static_use,
359 fragment_variables[ii].name);
360 break;
361 default:
362 NOTREACHED();
366 // Check we can create shader.
367 Shader* vshader = shader_manager_.CreateShader(
368 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
369 Shader* fshader = shader_manager_.CreateShader(
370 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
371 // Check shader got created.
372 EXPECT_TRUE(vshader != NULL && fshader != NULL);
373 // Set Status
374 TestHelper::SetShaderStates(
375 gl_.get(), vshader, true, NULL, NULL, NULL,
376 &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL);
377 TestHelper::SetShaderStates(
378 gl_.get(), fshader, true, NULL, NULL, NULL,
379 &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL);
381 // Set up program
382 const GLuint kClientProgramId = 6666;
383 const GLuint kServiceProgramId = 8888;
384 Program* program =
385 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
386 EXPECT_TRUE(program != NULL);
387 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
388 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
389 return program;
392 static AttribInfo kAttribs[];
393 static UniformInfo kUniforms[];
395 ProgramManager manager_;
396 Program* program_;
397 ShaderManager shader_manager_;
400 ProgramManagerWithShaderTest::AttribInfo
401 ProgramManagerWithShaderTest::kAttribs[] = {
402 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
403 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
404 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
407 // GCC requires these declarations, but MSVC requires they not be present
408 #ifndef COMPILER_MSVC
409 const GLint ProgramManagerWithShaderTest::kNumVertexAttribs;
410 const GLuint ProgramManagerWithShaderTest::kClientProgramId;
411 const GLuint ProgramManagerWithShaderTest::kServiceProgramId;
412 const GLuint ProgramManagerWithShaderTest::kVertexShaderClientId;
413 const GLuint ProgramManagerWithShaderTest::kFragmentShaderClientId;
414 const GLuint ProgramManagerWithShaderTest::kVertexShaderServiceId;
415 const GLuint ProgramManagerWithShaderTest::kFragmentShaderServiceId;
416 const GLint ProgramManagerWithShaderTest::kAttrib1Size;
417 const GLint ProgramManagerWithShaderTest::kAttrib2Size;
418 const GLint ProgramManagerWithShaderTest::kAttrib3Size;
419 const GLint ProgramManagerWithShaderTest::kAttrib1Location;
420 const GLint ProgramManagerWithShaderTest::kAttrib2Location;
421 const GLint ProgramManagerWithShaderTest::kAttrib3Location;
422 const GLenum ProgramManagerWithShaderTest::kAttrib1Type;
423 const GLenum ProgramManagerWithShaderTest::kAttrib2Type;
424 const GLenum ProgramManagerWithShaderTest::kAttrib3Type;
425 const GLint ProgramManagerWithShaderTest::kInvalidAttribLocation;
426 const GLint ProgramManagerWithShaderTest::kBadAttribIndex;
427 const GLint ProgramManagerWithShaderTest::kUniform1Size;
428 const GLint ProgramManagerWithShaderTest::kUniform2Size;
429 const GLint ProgramManagerWithShaderTest::kUniform3Size;
430 const GLint ProgramManagerWithShaderTest::kUniform1FakeLocation;
431 const GLint ProgramManagerWithShaderTest::kUniform2FakeLocation;
432 const GLint ProgramManagerWithShaderTest::kUniform3FakeLocation;
433 const GLint ProgramManagerWithShaderTest::kUniform1RealLocation;
434 const GLint ProgramManagerWithShaderTest::kUniform2RealLocation;
435 const GLint ProgramManagerWithShaderTest::kUniform3RealLocation;
436 const GLint ProgramManagerWithShaderTest::kUniform1DesiredLocation;
437 const GLint ProgramManagerWithShaderTest::kUniform2DesiredLocation;
438 const GLint ProgramManagerWithShaderTest::kUniform3DesiredLocation;
439 const GLenum ProgramManagerWithShaderTest::kUniform1Type;
440 const GLenum ProgramManagerWithShaderTest::kUniform2Type;
441 const GLenum ProgramManagerWithShaderTest::kUniform3Type;
442 const GLint ProgramManagerWithShaderTest::kInvalidUniformLocation;
443 const GLint ProgramManagerWithShaderTest::kBadUniformIndex;
444 #endif
446 const size_t ProgramManagerWithShaderTest::kNumAttribs =
447 arraysize(ProgramManagerWithShaderTest::kAttribs);
449 ProgramManagerWithShaderTest::UniformInfo
450 ProgramManagerWithShaderTest::kUniforms[] = {
451 { kUniform1Name,
452 kUniform1Size,
453 kUniform1Type,
454 kUniform1FakeLocation,
455 kUniform1RealLocation,
456 kUniform1DesiredLocation,
457 kUniform1Name,
459 { kUniform2Name,
460 kUniform2Size,
461 kUniform2Type,
462 kUniform2FakeLocation,
463 kUniform2RealLocation,
464 kUniform2DesiredLocation,
465 kUniform2NameWithArrayIndex,
467 { kUniform3Name,
468 kUniform3Size,
469 kUniform3Type,
470 kUniform3FakeLocation,
471 kUniform3RealLocation,
472 kUniform3DesiredLocation,
473 kUniform3NameWithArrayIndex,
477 const size_t ProgramManagerWithShaderTest::kNumUniforms =
478 arraysize(ProgramManagerWithShaderTest::kUniforms);
480 const char* ProgramManagerWithShaderTest::kAttrib1Name = "attrib1";
481 const char* ProgramManagerWithShaderTest::kAttrib2Name = "attrib2";
482 const char* ProgramManagerWithShaderTest::kAttrib3Name = "attrib3";
483 const char* ProgramManagerWithShaderTest::kUniform1Name = "uniform1";
484 const char* ProgramManagerWithShaderTest::kUniform2Name = "uniform2";
485 const char* ProgramManagerWithShaderTest::kUniform2NameWithArrayIndex =
486 "uniform2[0]";
487 const char* ProgramManagerWithShaderTest::kUniform3Name = "uniform3";
488 const char* ProgramManagerWithShaderTest::kUniform3NameWithArrayIndex =
489 "uniform3[0]";
491 TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) {
492 const Program* program = manager_.GetProgram(kClientProgramId);
493 ASSERT_TRUE(program != NULL);
494 const Program::AttribInfoVector& infos =
495 program->GetAttribInfos();
496 ASSERT_EQ(kNumAttribs, infos.size());
497 for (size_t ii = 0; ii < kNumAttribs; ++ii) {
498 const Program::VertexAttrib& info = infos[ii];
499 const AttribInfo& expected = kAttribs[ii];
500 EXPECT_EQ(expected.size, info.size);
501 EXPECT_EQ(expected.type, info.type);
502 EXPECT_EQ(expected.location, info.location);
503 EXPECT_STREQ(expected.name, info.name.c_str());
507 TEST_F(ProgramManagerWithShaderTest, GetAttribInfo) {
508 const GLint kValidIndex = 1;
509 const GLint kInvalidIndex = 1000;
510 const Program* program = manager_.GetProgram(kClientProgramId);
511 ASSERT_TRUE(program != NULL);
512 const Program::VertexAttrib* info =
513 program->GetAttribInfo(kValidIndex);
514 ASSERT_TRUE(info != NULL);
515 EXPECT_EQ(kAttrib2Size, info->size);
516 EXPECT_EQ(kAttrib2Type, info->type);
517 EXPECT_EQ(kAttrib2Location, info->location);
518 EXPECT_STREQ(kAttrib2Name, info->name.c_str());
519 EXPECT_TRUE(program->GetAttribInfo(kInvalidIndex) == NULL);
522 TEST_F(ProgramManagerWithShaderTest, GetAttribLocation) {
523 const char* kInvalidName = "foo";
524 const Program* program = manager_.GetProgram(kClientProgramId);
525 ASSERT_TRUE(program != NULL);
526 EXPECT_EQ(kAttrib2Location, program->GetAttribLocation(kAttrib2Name));
527 EXPECT_EQ(-1, program->GetAttribLocation(kInvalidName));
530 TEST_F(ProgramManagerWithShaderTest, GetUniformInfo) {
531 const GLint kInvalidIndex = 1000;
532 const Program* program = manager_.GetProgram(kClientProgramId);
533 ASSERT_TRUE(program != NULL);
534 const Program::UniformInfo* info =
535 program->GetUniformInfo(0);
536 ASSERT_TRUE(info != NULL);
537 EXPECT_EQ(kUniform1Size, info->size);
538 EXPECT_EQ(kUniform1Type, info->type);
539 EXPECT_EQ(kUniform1RealLocation, info->element_locations[0]);
540 EXPECT_STREQ(kUniform1Name, info->name.c_str());
541 info = program->GetUniformInfo(1);
542 ASSERT_TRUE(info != NULL);
543 EXPECT_EQ(kUniform2Size, info->size);
544 EXPECT_EQ(kUniform2Type, info->type);
545 EXPECT_EQ(kUniform2RealLocation, info->element_locations[0]);
546 EXPECT_STREQ(kUniform2NameWithArrayIndex, info->name.c_str());
547 info = program->GetUniformInfo(2);
548 // We emulate certain OpenGL drivers by supplying the name without
549 // the array spec. Our implementation should correctly add the required spec.
550 ASSERT_TRUE(info != NULL);
551 EXPECT_EQ(kUniform3Size, info->size);
552 EXPECT_EQ(kUniform3Type, info->type);
553 EXPECT_EQ(kUniform3RealLocation, info->element_locations[0]);
554 EXPECT_STREQ(kUniform3NameWithArrayIndex, info->name.c_str());
555 EXPECT_TRUE(program->GetUniformInfo(kInvalidIndex) == NULL);
558 TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) {
559 static const GLuint kClientProgramId = 124;
560 static const GLuint kServiceProgramId = 457;
561 Program* program = manager_.CreateProgram(
562 kClientProgramId, kServiceProgramId);
563 ASSERT_TRUE(program != NULL);
564 EXPECT_FALSE(program->CanLink());
565 const GLuint kVShaderClientId = 2001;
566 const GLuint kFShaderClientId = 2002;
567 const GLuint kVShaderServiceId = 3001;
568 const GLuint kFShaderServiceId = 3002;
569 Shader* vshader = shader_manager_.CreateShader(
570 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
571 ASSERT_TRUE(vshader != NULL);
572 TestHelper::SetShaderStates(gl_.get(), vshader, true);
573 Shader* fshader = shader_manager_.CreateShader(
574 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
575 ASSERT_TRUE(fshader != NULL);
576 TestHelper::SetShaderStates(gl_.get(), fshader, true);
577 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
578 EXPECT_FALSE(program->CanLink());
579 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
580 EXPECT_TRUE(program->CanLink());
581 program->DetachShader(&shader_manager_, vshader);
582 EXPECT_FALSE(program->CanLink());
583 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
584 EXPECT_TRUE(program->CanLink());
585 program->DetachShader(&shader_manager_, fshader);
586 EXPECT_FALSE(program->CanLink());
587 EXPECT_FALSE(program->AttachShader(&shader_manager_, vshader));
588 EXPECT_FALSE(program->CanLink());
589 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
590 EXPECT_TRUE(program->CanLink());
591 TestHelper::SetShaderStates(gl_.get(), vshader, false);
592 EXPECT_FALSE(program->CanLink());
593 TestHelper::SetShaderStates(gl_.get(), vshader, true);
594 EXPECT_TRUE(program->CanLink());
595 TestHelper::SetShaderStates(gl_.get(), fshader, false);
596 EXPECT_FALSE(program->CanLink());
597 TestHelper::SetShaderStates(gl_.get(), fshader, true);
598 EXPECT_TRUE(program->CanLink());
599 EXPECT_TRUE(program->DetachShader(&shader_manager_, fshader));
600 EXPECT_FALSE(program->DetachShader(&shader_manager_, fshader));
603 TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) {
604 const Program* program = manager_.GetProgram(kClientProgramId);
605 ASSERT_TRUE(program != NULL);
606 // Emulate the situation that uniform3[1] isn't used and optimized out by
607 // a driver, so it's location is -1.
608 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
609 program->GetUniformInfo(2));
610 ASSERT_TRUE(uniform != NULL && kUniform3Size == 2);
611 EXPECT_EQ(kUniform3Size, uniform->size);
612 uniform->element_locations[1] = -1;
613 EXPECT_EQ(kUniform1FakeLocation,
614 program->GetUniformFakeLocation(kUniform1Name));
615 EXPECT_EQ(kUniform2FakeLocation,
616 program->GetUniformFakeLocation(kUniform2Name));
617 EXPECT_EQ(kUniform3FakeLocation,
618 program->GetUniformFakeLocation(kUniform3Name));
619 // Check we can get uniform2 as "uniform2" even though the name is
620 // "uniform2[0]"
621 EXPECT_EQ(kUniform2FakeLocation,
622 program->GetUniformFakeLocation("uniform2"));
623 // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
624 // returning "uniform3"
625 EXPECT_EQ(kUniform3FakeLocation,
626 program->GetUniformFakeLocation(kUniform3NameWithArrayIndex));
627 // Check that we can get the locations of the array elements > 1
628 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 1),
629 program->GetUniformFakeLocation("uniform2[1]"));
630 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2),
631 program->GetUniformFakeLocation("uniform2[2]"));
632 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]"));
633 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[1]"));
634 EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]"));
637 TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) {
638 const GLint kInvalidLocation = 1234;
639 const Program::UniformInfo* info;
640 const Program* program = manager_.GetProgram(kClientProgramId);
641 GLint real_location = -1;
642 GLint array_index = -1;
643 ASSERT_TRUE(program != NULL);
644 info = program->GetUniformInfoByFakeLocation(
645 kUniform2FakeLocation, &real_location, &array_index);
646 EXPECT_EQ(kUniform2RealLocation, real_location);
647 EXPECT_EQ(0, array_index);
648 ASSERT_TRUE(info != NULL);
649 EXPECT_EQ(kUniform2Type, info->type);
650 real_location = -1;
651 array_index = -1;
652 info = program->GetUniformInfoByFakeLocation(
653 kInvalidLocation, &real_location, &array_index);
654 EXPECT_TRUE(info == NULL);
655 EXPECT_EQ(-1, real_location);
656 EXPECT_EQ(-1, array_index);
657 GLint loc = program->GetUniformFakeLocation("uniform2[2]");
658 info = program->GetUniformInfoByFakeLocation(
659 loc, &real_location, &array_index);
660 ASSERT_TRUE(info != NULL);
661 EXPECT_EQ(kUniform2RealLocation + 2 * 2, real_location);
662 EXPECT_EQ(2, array_index);
665 // Ensure that when GL drivers correctly return gl_DepthRange, or other
666 // builtin uniforms, our implementation passes them back to the client.
667 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
668 static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
669 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
671 kUniform1Name,
672 kUniform1Size,
673 kUniform1Type,
674 kUniform1FakeLocation,
675 kUniform1RealLocation,
676 kUniform1DesiredLocation,
677 kUniform1Name,
680 kUniform2Name,
681 kUniform2Size,
682 kUniform2Type,
683 kUniform2FakeLocation,
685 kUniform2DesiredLocation,
686 kUniform2NameWithArrayIndex,
689 kUniform3Name,
690 kUniform3Size,
691 kUniform3Type,
692 kUniform3FakeLocation,
693 kUniform3RealLocation,
694 kUniform3DesiredLocation,
695 kUniform3NameWithArrayIndex,
698 const size_t kNumUniforms = arraysize(kUniforms);
699 static const GLuint kClientProgramId = 1234;
700 static const GLuint kServiceProgramId = 5679;
701 const GLuint kVShaderClientId = 2001;
702 const GLuint kFShaderClientId = 2002;
703 const GLuint kVShaderServiceId = 3001;
704 const GLuint kFShaderServiceId = 3002;
705 SetupShader(
706 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
707 Shader* vshader = shader_manager_.CreateShader(
708 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
709 ASSERT_TRUE(vshader != NULL);
710 TestHelper::SetShaderStates(gl_.get(), vshader, true);
711 Shader* fshader = shader_manager_.CreateShader(
712 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
713 ASSERT_TRUE(fshader != NULL);
714 TestHelper::SetShaderStates(gl_.get(), fshader, true);
715 Program* program =
716 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
717 ASSERT_TRUE(program != NULL);
718 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
719 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
720 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
721 base::Bind(&ShaderCacheCb));
722 GLint value = 0;
723 program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
724 EXPECT_EQ(3, value);
725 // Check that we didn't skip the "gl_" uniform.
726 program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
727 EXPECT_EQ(3, value);
728 // Check that our max length adds room for the array spec and is as long
729 // as the "gl_" uniform we did not skip.
730 program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
731 EXPECT_EQ(strlen(kUniform2Name) + 4, static_cast<size_t>(value));
732 // Verify the uniform has a "real" location of -1
733 const auto* info = program->GetUniformInfo(kUniform2FakeLocation);
734 EXPECT_EQ(-1, info->element_locations[0]);
737 // Test the bug comparing similar array names is fixed.
738 TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
739 static const char* kUniform2Name = "u_nameLong[0]";
740 static const char* kUniform3Name = "u_name[0]";
741 static const GLint kUniform2Size = 2;
742 static const GLint kUniform3Size = 2;
743 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
744 { kUniform1Name,
745 kUniform1Size,
746 kUniform1Type,
747 kUniform1FakeLocation,
748 kUniform1RealLocation,
749 kUniform1DesiredLocation,
750 kUniform1Name,
752 { kUniform2Name,
753 kUniform2Size,
754 kUniform2Type,
755 kUniform2FakeLocation,
756 kUniform2RealLocation,
757 kUniform2DesiredLocation,
758 kUniform2Name,
760 { kUniform3Name,
761 kUniform3Size,
762 kUniform3Type,
763 kUniform3FakeLocation,
764 kUniform3RealLocation,
765 kUniform3DesiredLocation,
766 kUniform3Name,
769 const size_t kNumUniforms = arraysize(kUniforms);
770 static const GLuint kClientProgramId = 1234;
771 static const GLuint kServiceProgramId = 5679;
772 const GLuint kVShaderClientId = 2001;
773 const GLuint kFShaderClientId = 2002;
774 const GLuint kVShaderServiceId = 3001;
775 const GLuint kFShaderServiceId = 3002;
776 SetupShader(
777 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
778 Shader* vshader = shader_manager_.CreateShader(
779 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
780 ASSERT_TRUE(vshader != NULL);
781 TestHelper::SetShaderStates(gl_.get(), vshader, true);
782 Shader* fshader = shader_manager_.CreateShader(
783 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
784 ASSERT_TRUE(fshader != NULL);
785 TestHelper::SetShaderStates(gl_.get(), fshader, true);
786 Program* program =
787 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
788 ASSERT_TRUE(program != NULL);
789 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
790 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
791 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
792 base::Bind(&ShaderCacheCb));
794 // Check that we get the correct locations.
795 EXPECT_EQ(kUniform2FakeLocation,
796 program->GetUniformFakeLocation(kUniform2Name));
797 EXPECT_EQ(kUniform3FakeLocation,
798 program->GetUniformFakeLocation(kUniform3Name));
801 // Some GL drivers incorrectly return the wrong type. For example they return
802 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
803 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
804 static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
805 static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
806 static GLenum kUniform2BadType = GL_FLOAT_VEC3;
807 static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
808 AttributeMap attrib_map;
809 UniformMap uniform_map;
810 VaryingMap varying_map;
811 attrib_map[kAttrib1Name] = TestHelper::ConstructAttribute(
812 kAttrib1Type, kAttrib1Size, kAttrib1Precision,
813 kAttribStaticUse, kAttrib1Name);
814 attrib_map[kAttrib2Name] = TestHelper::ConstructAttribute(
815 kAttrib2GoodType, kAttrib2Size, kAttrib2Precision,
816 kAttribStaticUse, kAttrib2Name);
817 attrib_map[kAttrib3Name] = TestHelper::ConstructAttribute(
818 kAttrib3Type, kAttrib3Size, kAttrib3Precision,
819 kAttribStaticUse, kAttrib3Name);
820 uniform_map[kUniform1Name] = TestHelper::ConstructUniform(
821 kUniform1Type, kUniform1Size, kUniform1Precision,
822 kUniform1StaticUse, kUniform1Name);
823 uniform_map[kUniform2Name] = TestHelper::ConstructUniform(
824 kUniform2GoodType, kUniform2Size, kUniform2Precision,
825 kUniform2StaticUse, kUniform2Name);
826 uniform_map[kUniform3Name] = TestHelper::ConstructUniform(
827 kUniform3Type, kUniform3Size, kUniform3Precision,
828 kUniform3StaticUse, kUniform3Name);
829 const GLuint kVShaderClientId = 2001;
830 const GLuint kFShaderClientId = 2002;
831 const GLuint kVShaderServiceId = 3001;
832 const GLuint kFShaderServiceId = 3002;
833 Shader* vshader = shader_manager_.CreateShader(
834 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
835 ASSERT_TRUE(vshader != NULL);
836 TestHelper::SetShaderStates(
837 gl_.get(), vshader, true, NULL, NULL, NULL,
838 &attrib_map, &uniform_map, &varying_map, NULL);
839 Shader* fshader = shader_manager_.CreateShader(
840 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
841 ASSERT_TRUE(fshader != NULL);
842 TestHelper::SetShaderStates(
843 gl_.get(), fshader, true, NULL, NULL, NULL,
844 &attrib_map, &uniform_map, &varying_map, NULL);
845 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
846 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
847 { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
848 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
850 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
851 { kUniform1Name,
852 kUniform1Size,
853 kUniform1Type,
854 kUniform1FakeLocation,
855 kUniform1RealLocation,
856 kUniform1DesiredLocation,
857 kUniform1Name,
859 { kUniform2Name,
860 kUniform2Size,
861 kUniform2BadType,
862 kUniform2FakeLocation,
863 kUniform2RealLocation,
864 kUniform2DesiredLocation,
865 kUniform2NameWithArrayIndex,
867 { kUniform3Name,
868 kUniform3Size,
869 kUniform3Type,
870 kUniform3FakeLocation,
871 kUniform3RealLocation,
872 kUniform3DesiredLocation,
873 kUniform3NameWithArrayIndex,
876 const size_t kNumAttribs= arraysize(kAttribs);
877 const size_t kNumUniforms = arraysize(kUniforms);
878 static const GLuint kClientProgramId = 1234;
879 static const GLuint kServiceProgramId = 5679;
880 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
881 kServiceProgramId);
882 Program* program = manager_.CreateProgram(
883 kClientProgramId, kServiceProgramId);
884 ASSERT_TRUE(program!= NULL);
885 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
886 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
887 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
888 base::Bind(&ShaderCacheCb));
889 // Check that we got the good type, not the bad.
890 // Check Attribs
891 for (unsigned index = 0; index < kNumAttribs; ++index) {
892 const Program::VertexAttrib* attrib_info =
893 program->GetAttribInfo(index);
894 ASSERT_TRUE(attrib_info != NULL);
895 size_t pos = attrib_info->name.find_first_of("[.");
896 std::string top_name;
897 if (pos == std::string::npos)
898 top_name = attrib_info->name;
899 else
900 top_name = attrib_info->name.substr(0, pos);
901 AttributeMap::const_iterator it = attrib_map.find(top_name);
902 ASSERT_TRUE(it != attrib_map.end());
903 const sh::ShaderVariable* info;
904 std::string original_name;
905 EXPECT_TRUE(it->second.findInfoByMappedName(
906 attrib_info->name, &info, &original_name));
907 EXPECT_EQ(info->type, attrib_info->type);
908 EXPECT_EQ(static_cast<GLint>(info->arraySize), attrib_info->size);
909 EXPECT_EQ(original_name, attrib_info->name);
911 // Check Uniforms
912 for (unsigned index = 0; index < kNumUniforms; ++index) {
913 const Program::UniformInfo* uniform_info = program->GetUniformInfo(index);
914 ASSERT_TRUE(uniform_info != NULL);
915 size_t pos = uniform_info->name.find_first_of("[.");
916 std::string top_name;
917 if (pos == std::string::npos)
918 top_name = uniform_info->name;
919 else
920 top_name = uniform_info->name.substr(0, pos);
921 UniformMap::const_iterator it = uniform_map.find(top_name);
922 ASSERT_TRUE(it != uniform_map.end());
923 const sh::ShaderVariable* info;
924 std::string original_name;
925 EXPECT_TRUE(it->second.findInfoByMappedName(
926 uniform_info->name, &info, &original_name));
927 EXPECT_EQ(info->type, uniform_info->type);
928 EXPECT_EQ(static_cast<GLint>(info->arraySize), uniform_info->size);
929 EXPECT_EQ(original_name, uniform_info->name);
933 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
934 static const GLuint kClientProgramId = 124;
935 static const GLuint kServiceProgramId = 457;
936 Program* program = manager_.CreateProgram(
937 kClientProgramId, kServiceProgramId);
938 ASSERT_TRUE(program != NULL);
939 EXPECT_FALSE(program->CanLink());
940 const GLuint kVShaderClientId = 2001;
941 const GLuint kFShaderClientId = 2002;
942 const GLuint kVShaderServiceId = 3001;
943 const GLuint kFShaderServiceId = 3002;
944 Shader* vshader = shader_manager_.CreateShader(
945 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
946 ASSERT_TRUE(vshader != NULL);
947 TestHelper::SetShaderStates(gl_.get(), vshader, true);
948 Shader* fshader = shader_manager_.CreateShader(
949 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
950 ASSERT_TRUE(fshader != NULL);
951 TestHelper::SetShaderStates(gl_.get(), fshader, true);
952 EXPECT_FALSE(vshader->InUse());
953 EXPECT_FALSE(fshader->InUse());
954 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
955 EXPECT_TRUE(vshader->InUse());
956 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
957 EXPECT_TRUE(fshader->InUse());
958 EXPECT_TRUE(program->CanLink());
959 EXPECT_FALSE(program->InUse());
960 EXPECT_FALSE(program->IsDeleted());
961 manager_.UseProgram(program);
962 EXPECT_TRUE(program->InUse());
963 manager_.UseProgram(program);
964 EXPECT_TRUE(program->InUse());
965 manager_.MarkAsDeleted(&shader_manager_, program);
966 EXPECT_TRUE(program->IsDeleted());
967 Program* info2 = manager_.GetProgram(kClientProgramId);
968 EXPECT_EQ(program, info2);
969 manager_.UnuseProgram(&shader_manager_, program);
970 EXPECT_TRUE(program->InUse());
971 // this should delete the info.
972 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
973 .Times(1)
974 .RetiresOnSaturation();
975 manager_.UnuseProgram(&shader_manager_, program);
976 info2 = manager_.GetProgram(kClientProgramId);
977 EXPECT_TRUE(info2 == NULL);
978 EXPECT_FALSE(vshader->InUse());
979 EXPECT_FALSE(fshader->InUse());
982 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
983 static const GLuint kClientProgramId = 124;
984 static const GLuint kServiceProgramId = 457;
985 Program* program = manager_.CreateProgram(
986 kClientProgramId, kServiceProgramId);
987 ASSERT_TRUE(program != NULL);
988 EXPECT_FALSE(program->CanLink());
989 const GLuint kVShaderClientId = 2001;
990 const GLuint kFShaderClientId = 2002;
991 const GLuint kVShaderServiceId = 3001;
992 const GLuint kFShaderServiceId = 3002;
993 Shader* vshader = shader_manager_.CreateShader(
994 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
995 ASSERT_TRUE(vshader != NULL);
996 TestHelper::SetShaderStates(gl_.get(), vshader, true);
997 Shader* fshader = shader_manager_.CreateShader(
998 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
999 ASSERT_TRUE(fshader != NULL);
1000 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1001 EXPECT_FALSE(vshader->InUse());
1002 EXPECT_FALSE(fshader->InUse());
1003 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1004 EXPECT_TRUE(vshader->InUse());
1005 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1006 EXPECT_TRUE(fshader->InUse());
1007 EXPECT_TRUE(program->CanLink());
1008 EXPECT_FALSE(program->InUse());
1009 EXPECT_FALSE(program->IsDeleted());
1010 manager_.UseProgram(program);
1011 EXPECT_TRUE(program->InUse());
1012 manager_.UseProgram(program);
1013 EXPECT_TRUE(program->InUse());
1014 manager_.UnuseProgram(&shader_manager_, program);
1015 EXPECT_TRUE(program->InUse());
1016 manager_.UnuseProgram(&shader_manager_, program);
1017 EXPECT_FALSE(program->InUse());
1018 Program* info2 = manager_.GetProgram(kClientProgramId);
1019 EXPECT_EQ(program, info2);
1020 // this should delete the program.
1021 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
1022 .Times(1)
1023 .RetiresOnSaturation();
1024 manager_.MarkAsDeleted(&shader_manager_, program);
1025 info2 = manager_.GetProgram(kClientProgramId);
1026 EXPECT_TRUE(info2 == NULL);
1027 EXPECT_FALSE(vshader->InUse());
1028 EXPECT_FALSE(fshader->InUse());
1031 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
1032 CommonDecoder::Bucket bucket;
1033 const Program* program = manager_.GetProgram(kClientProgramId);
1034 ASSERT_TRUE(program != NULL);
1035 program->GetProgramInfo(&manager_, &bucket);
1036 ProgramInfoHeader* header =
1037 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1038 ASSERT_TRUE(header != NULL);
1039 EXPECT_EQ(1u, header->link_status);
1040 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1041 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1042 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1043 sizeof(*header),
1044 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1045 ASSERT_TRUE(inputs != NULL);
1046 const ProgramInput* input = inputs;
1047 // TODO(gman): Don't assume these are in order.
1048 for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
1049 const AttribInfo& expected = kAttribs[ii];
1050 EXPECT_EQ(expected.size, input->size);
1051 EXPECT_EQ(expected.type, input->type);
1052 const int32* location = bucket.GetDataAs<const int32*>(
1053 input->location_offset, sizeof(int32));
1054 ASSERT_TRUE(location != NULL);
1055 EXPECT_EQ(expected.location, *location);
1056 const char* name_buf = bucket.GetDataAs<const char*>(
1057 input->name_offset, input->name_length);
1058 ASSERT_TRUE(name_buf != NULL);
1059 std::string name(name_buf, input->name_length);
1060 EXPECT_STREQ(expected.name, name.c_str());
1061 ++input;
1063 // TODO(gman): Don't assume these are in order.
1064 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1065 const UniformInfo& expected = kUniforms[ii];
1066 EXPECT_EQ(expected.size, input->size);
1067 EXPECT_EQ(expected.type, input->type);
1068 const int32* locations = bucket.GetDataAs<const int32*>(
1069 input->location_offset, sizeof(int32) * input->size);
1070 ASSERT_TRUE(locations != NULL);
1071 for (int32 jj = 0; jj < input->size; ++jj) {
1072 EXPECT_EQ(
1073 ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1074 locations[jj]);
1076 const char* name_buf = bucket.GetDataAs<const char*>(
1077 input->name_offset, input->name_length);
1078 ASSERT_TRUE(name_buf != NULL);
1079 std::string name(name_buf, input->name_length);
1080 EXPECT_STREQ(expected.good_name, name.c_str());
1081 ++input;
1083 EXPECT_EQ(header->num_attribs + header->num_uniforms,
1084 static_cast<uint32>(input - inputs));
1087 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksNone) {
1088 CommonDecoder::Bucket bucket;
1089 const Program* program = manager_.GetProgram(kClientProgramId);
1090 ASSERT_TRUE(program != NULL);
1091 // The program's previous link failed.
1092 EXPECT_CALL(*(gl_.get()),
1093 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1094 .WillOnce(SetArgPointee<2>(GL_FALSE))
1095 .RetiresOnSaturation();
1096 EXPECT_TRUE(program->GetUniformBlocks(&bucket));
1097 EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size());
1098 UniformBlocksHeader* header =
1099 bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader));
1100 EXPECT_TRUE(header != NULL);
1101 EXPECT_EQ(0u, header->num_uniform_blocks);
1102 // Zero uniform blocks.
1103 EXPECT_CALL(*(gl_.get()),
1104 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1105 .WillOnce(SetArgPointee<2>(GL_TRUE))
1106 .RetiresOnSaturation();
1107 EXPECT_CALL(*(gl_.get()),
1108 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _))
1109 .WillOnce(SetArgPointee<2>(0))
1110 .RetiresOnSaturation();
1111 EXPECT_TRUE(program->GetUniformBlocks(&bucket));
1112 EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size());
1113 header =
1114 bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader));
1115 EXPECT_TRUE(header != NULL);
1116 EXPECT_EQ(0u, header->num_uniform_blocks);
1119 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksValid) {
1120 CommonDecoder::Bucket bucket;
1121 const Program* program = manager_.GetProgram(kClientProgramId);
1122 ASSERT_TRUE(program != NULL);
1123 struct Data {
1124 UniformBlocksHeader header;
1125 UniformBlockInfo entry[2];
1126 char name0[4];
1127 uint32_t indices0[2];
1128 char name1[8];
1129 uint32_t indices1[1];
1131 Data data;
1132 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1133 // This is a testing only problem.
1134 const char* kName[] = { "cow", "chicken" };
1135 const uint32_t kIndices0[] = { 1, 2 };
1136 const uint32_t kIndices1[] = { 3 };
1137 const uint32_t* kIndices[] = { kIndices0, kIndices1 };
1138 data.header.num_uniform_blocks = 2;
1139 data.entry[0].binding = 0;
1140 data.entry[0].data_size = 8;
1141 data.entry[0].name_offset = ComputeOffset(&data, data.name0);
1142 data.entry[0].name_length = arraysize(data.name0);
1143 data.entry[0].active_uniforms = arraysize(data.indices0);
1144 data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0);
1145 data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true);
1146 data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false);
1147 data.entry[1].binding = 1;
1148 data.entry[1].data_size = 4;
1149 data.entry[1].name_offset = ComputeOffset(&data, data.name1);
1150 data.entry[1].name_length = arraysize(data.name1);
1151 data.entry[1].active_uniforms = arraysize(data.indices1);
1152 data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1);
1153 data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false);
1154 data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true);
1155 memcpy(data.name0, kName[0], arraysize(data.name0));
1156 data.indices0[0] = kIndices[0][0];
1157 data.indices0[1] = kIndices[0][1];
1158 memcpy(data.name1, kName[1], arraysize(data.name1));
1159 data.indices1[0] = kIndices[1][0];
1161 EXPECT_CALL(*(gl_.get()),
1162 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1163 .WillOnce(SetArgPointee<2>(GL_TRUE))
1164 .RetiresOnSaturation();
1165 EXPECT_CALL(*(gl_.get()),
1166 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _))
1167 .WillOnce(SetArgPointee<2>(data.header.num_uniform_blocks))
1168 .RetiresOnSaturation();
1169 EXPECT_CALL(*(gl_.get()),
1170 GetProgramiv(kServiceProgramId,
1171 GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, _))
1172 .WillOnce(SetArgPointee<2>(
1173 1 + std::max(strlen(kName[0]), strlen(kName[1]))))
1174 .RetiresOnSaturation();
1175 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) {
1176 EXPECT_CALL(*(gl_.get()),
1177 GetActiveUniformBlockiv(
1178 kServiceProgramId, ii, GL_UNIFORM_BLOCK_BINDING, _))
1179 .WillOnce(SetArgPointee<3>(data.entry[ii].binding))
1180 .RetiresOnSaturation();
1181 EXPECT_CALL(*(gl_.get()),
1182 GetActiveUniformBlockiv(
1183 kServiceProgramId, ii, GL_UNIFORM_BLOCK_DATA_SIZE, _))
1184 .WillOnce(SetArgPointee<3>(data.entry[ii].data_size))
1185 .RetiresOnSaturation();
1186 EXPECT_CALL(*(gl_.get()),
1187 GetActiveUniformBlockiv(
1188 kServiceProgramId, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, _))
1189 .WillOnce(SetArgPointee<3>(data.entry[ii].name_length))
1190 .RetiresOnSaturation();
1191 EXPECT_CALL(*(gl_.get()),
1192 GetActiveUniformBlockName(
1193 kServiceProgramId, ii, data.entry[ii].name_length, _, _))
1194 .WillOnce(DoAll(
1195 SetArgPointee<3>(strlen(kName[ii])),
1196 SetArrayArgument<4>(
1197 kName[ii], kName[ii] + data.entry[ii].name_length)))
1198 .RetiresOnSaturation();
1199 EXPECT_CALL(*(gl_.get()),
1200 GetActiveUniformBlockiv(
1201 kServiceProgramId, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _))
1202 .WillOnce(SetArgPointee<3>(data.entry[ii].active_uniforms))
1203 .RetiresOnSaturation();
1204 EXPECT_CALL(*(gl_.get()),
1205 GetActiveUniformBlockiv(
1206 kServiceProgramId, ii,
1207 GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, _))
1208 .WillOnce(SetArgPointee<3>(data.entry[ii].referenced_by_vertex_shader))
1209 .RetiresOnSaturation();
1210 EXPECT_CALL(*(gl_.get()),
1211 GetActiveUniformBlockiv(
1212 kServiceProgramId, ii,
1213 GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, _))
1214 .WillOnce(SetArgPointee<3>(
1215 data.entry[ii].referenced_by_fragment_shader))
1216 .RetiresOnSaturation();
1218 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) {
1219 EXPECT_CALL(*(gl_.get()),
1220 GetActiveUniformBlockiv(
1221 kServiceProgramId, ii,
1222 GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, _))
1223 .WillOnce(SetArrayArgument<3>(
1224 kIndices[ii], kIndices[ii] + data.entry[ii].active_uniforms))
1225 .RetiresOnSaturation();
1227 program->GetUniformBlocks(&bucket);
1228 EXPECT_EQ(sizeof(Data), bucket.size());
1229 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1230 EXPECT_TRUE(bucket_data != NULL);
1231 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1234 TEST_F(ProgramManagerWithShaderTest,
1235 ProgramInfoGetTransformFeedbackVaryingsNone) {
1236 CommonDecoder::Bucket bucket;
1237 const Program* program = manager_.GetProgram(kClientProgramId);
1238 ASSERT_TRUE(program != NULL);
1239 // The program's previous link failed.
1240 EXPECT_CALL(*(gl_.get()),
1241 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1242 .WillOnce(SetArgPointee<2>(GL_FALSE))
1243 .RetiresOnSaturation();
1244 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1245 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1246 TransformFeedbackVaryingsHeader* header =
1247 bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1248 0, sizeof(TransformFeedbackVaryingsHeader));
1249 EXPECT_TRUE(header != NULL);
1250 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1251 // Zero uniform blocks.
1252 EXPECT_CALL(*(gl_.get()),
1253 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1254 .WillOnce(SetArgPointee<2>(GL_TRUE))
1255 .RetiresOnSaturation();
1256 EXPECT_CALL(*(gl_.get()),
1257 GetProgramiv(
1258 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1259 .WillOnce(SetArgPointee<2>(0))
1260 .RetiresOnSaturation();
1261 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1262 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1263 header = bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1264 0, sizeof(TransformFeedbackVaryingsHeader));
1265 EXPECT_TRUE(header != NULL);
1266 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1269 TEST_F(ProgramManagerWithShaderTest,
1270 ProgramInfoGetTransformFeedbackVaryingsValid) {
1271 CommonDecoder::Bucket bucket;
1272 const Program* program = manager_.GetProgram(kClientProgramId);
1273 ASSERT_TRUE(program != NULL);
1274 struct Data {
1275 TransformFeedbackVaryingsHeader header;
1276 TransformFeedbackVaryingInfo entry[2];
1277 char name0[4];
1278 char name1[8];
1280 Data data;
1281 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1282 // This is a testing only problem.
1283 const char* kName[] = { "cow", "chicken" };
1284 data.header.num_transform_feedback_varyings = 2;
1285 data.entry[0].size = 1;
1286 data.entry[0].type = GL_FLOAT_VEC2;
1287 data.entry[0].name_offset = ComputeOffset(&data, data.name0);
1288 data.entry[0].name_length = arraysize(data.name0);
1289 data.entry[1].size = 2;
1290 data.entry[1].type = GL_FLOAT;
1291 data.entry[1].name_offset = ComputeOffset(&data, data.name1);
1292 data.entry[1].name_length = arraysize(data.name1);
1293 memcpy(data.name0, kName[0], arraysize(data.name0));
1294 memcpy(data.name1, kName[1], arraysize(data.name1));
1296 EXPECT_CALL(*(gl_.get()),
1297 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1298 .WillOnce(SetArgPointee<2>(GL_TRUE))
1299 .RetiresOnSaturation();
1300 EXPECT_CALL(*(gl_.get()),
1301 GetProgramiv(
1302 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1303 .WillOnce(SetArgPointee<2>(data.header.num_transform_feedback_varyings))
1304 .RetiresOnSaturation();
1305 GLsizei max_length = 1 + std::max(strlen(kName[0]), strlen(kName[1]));
1306 EXPECT_CALL(*(gl_.get()),
1307 GetProgramiv(kServiceProgramId,
1308 GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _))
1309 .WillOnce(SetArgPointee<2>(max_length))
1310 .RetiresOnSaturation();
1311 for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings;
1312 ++ii) {
1313 EXPECT_CALL(*(gl_.get()),
1314 GetTransformFeedbackVarying(
1315 kServiceProgramId, ii, max_length, _, _, _, _))
1316 .WillOnce(DoAll(
1317 SetArgPointee<3>(data.entry[ii].name_length - 1),
1318 SetArgPointee<4>(data.entry[ii].size),
1319 SetArgPointee<5>(data.entry[ii].type),
1320 SetArrayArgument<6>(
1321 kName[ii], kName[ii] + data.entry[ii].name_length)))
1322 .RetiresOnSaturation();
1324 program->GetTransformFeedbackVaryings(&bucket);
1325 EXPECT_EQ(sizeof(Data), bucket.size());
1326 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1327 EXPECT_TRUE(bucket_data != NULL);
1328 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1331 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3None) {
1332 CommonDecoder::Bucket bucket;
1333 const Program* program = manager_.GetProgram(kClientProgramId);
1334 ASSERT_TRUE(program != NULL);
1335 // The program's previous link failed.
1336 EXPECT_CALL(*(gl_.get()),
1337 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1338 .WillOnce(SetArgPointee<2>(GL_FALSE))
1339 .RetiresOnSaturation();
1340 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1341 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1342 UniformsES3Header* header =
1343 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1344 EXPECT_TRUE(header != NULL);
1345 EXPECT_EQ(0u, header->num_uniforms);
1346 // Zero uniform blocks.
1347 EXPECT_CALL(*(gl_.get()),
1348 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1349 .WillOnce(SetArgPointee<2>(GL_TRUE))
1350 .RetiresOnSaturation();
1351 EXPECT_CALL(*(gl_.get()),
1352 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1353 .WillOnce(SetArgPointee<2>(0))
1354 .RetiresOnSaturation();
1355 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1356 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1357 header =
1358 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1359 EXPECT_TRUE(header != NULL);
1360 EXPECT_EQ(0u, header->num_uniforms);
1363 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3Valid) {
1364 CommonDecoder::Bucket bucket;
1365 const Program* program = manager_.GetProgram(kClientProgramId);
1366 ASSERT_TRUE(program != NULL);
1367 struct Data {
1368 UniformsES3Header header;
1369 UniformES3Info entry[2];
1371 Data data;
1372 const GLint kBlockIndex[] = { -1, 2 };
1373 const GLint kOffset[] = { 3, 4 };
1374 const GLint kArrayStride[] = { 7, 8 };
1375 const GLint kMatrixStride[] = { 9, 10 };
1376 const GLint kIsRowMajor[] = { 0, 1 };
1377 data.header.num_uniforms = 2;
1378 for (uint32_t ii = 0; ii < data.header.num_uniforms; ++ii) {
1379 data.entry[ii].block_index = kBlockIndex[ii];
1380 data.entry[ii].offset = kOffset[ii];
1381 data.entry[ii].array_stride = kArrayStride[ii];
1382 data.entry[ii].matrix_stride = kMatrixStride[ii];
1383 data.entry[ii].is_row_major = kIsRowMajor[ii];
1386 EXPECT_CALL(*(gl_.get()),
1387 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1388 .WillOnce(SetArgPointee<2>(GL_TRUE))
1389 .RetiresOnSaturation();
1390 EXPECT_CALL(*(gl_.get()),
1391 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1392 .WillOnce(SetArgPointee<2>(data.header.num_uniforms))
1393 .RetiresOnSaturation();
1395 const GLenum kPname[] = {
1396 GL_UNIFORM_BLOCK_INDEX,
1397 GL_UNIFORM_OFFSET,
1398 GL_UNIFORM_ARRAY_STRIDE,
1399 GL_UNIFORM_MATRIX_STRIDE,
1400 GL_UNIFORM_IS_ROW_MAJOR,
1402 const GLint* kParams[] = {
1403 kBlockIndex,
1404 kOffset,
1405 kArrayStride,
1406 kMatrixStride,
1407 kIsRowMajor,
1409 const size_t kNumIterations = arraysize(kPname);
1410 for (size_t ii = 0; ii < kNumIterations; ++ii) {
1411 EXPECT_CALL(*(gl_.get()),
1412 GetActiveUniformsiv(
1413 kServiceProgramId, data.header.num_uniforms, _,
1414 kPname[ii], _))
1415 .WillOnce(SetArrayArgument<4>(
1416 kParams[ii], kParams[ii] + data.header.num_uniforms))
1417 .RetiresOnSaturation();
1420 program->GetUniformsES3(&bucket);
1421 EXPECT_EQ(sizeof(Data), bucket.size());
1422 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1423 EXPECT_TRUE(bucket_data != NULL);
1424 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1427 // Some drivers optimize out unused uniform array elements, so their
1428 // location would be -1.
1429 TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
1430 CommonDecoder::Bucket bucket;
1431 const Program* program = manager_.GetProgram(kClientProgramId);
1432 ASSERT_TRUE(program != NULL);
1433 // Emulate the situation that only the first element has a valid location.
1434 // TODO(zmo): Don't assume these are in order.
1435 for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
1436 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
1437 program->GetUniformInfo(ii));
1438 ASSERT_TRUE(uniform != NULL);
1439 EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
1440 uniform->element_locations.size());
1441 for (GLsizei jj = 1; jj < uniform->size; ++jj)
1442 uniform->element_locations[jj] = -1;
1444 program->GetProgramInfo(&manager_, &bucket);
1445 ProgramInfoHeader* header =
1446 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1447 ASSERT_TRUE(header != NULL);
1448 EXPECT_EQ(1u, header->link_status);
1449 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1450 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1451 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1452 sizeof(*header),
1453 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1454 ASSERT_TRUE(inputs != NULL);
1455 const ProgramInput* input = inputs + header->num_attribs;
1456 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1457 const UniformInfo& expected = kUniforms[ii];
1458 EXPECT_EQ(expected.size, input->size);
1459 const int32* locations = bucket.GetDataAs<const int32*>(
1460 input->location_offset, sizeof(int32) * input->size);
1461 ASSERT_TRUE(locations != NULL);
1462 EXPECT_EQ(
1463 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1464 locations[0]);
1465 for (int32 jj = 1; jj < input->size; ++jj)
1466 EXPECT_EQ(-1, locations[jj]);
1467 ++input;
1471 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1472 // Set up shader
1473 const GLuint kVShaderClientId = 1;
1474 const GLuint kVShaderServiceId = 11;
1475 const GLuint kFShaderClientId = 2;
1476 const GLuint kFShaderServiceId = 12;
1477 AttributeMap attrib_map;
1478 for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
1479 attrib_map[kAttribs[ii].name] = TestHelper::ConstructAttribute(
1480 kAttribs[ii].type,
1481 kAttribs[ii].size,
1482 GL_MEDIUM_FLOAT,
1483 kAttribStaticUse,
1484 kAttribs[ii].name);
1486 const char kAttribMatName[] = "matAttrib";
1487 attrib_map[kAttribMatName] = TestHelper::ConstructAttribute(
1488 GL_FLOAT_MAT2,
1490 GL_MEDIUM_FLOAT,
1491 kAttribStaticUse,
1492 kAttribMatName);
1493 // Check we can create shader.
1494 Shader* vshader = shader_manager_.CreateShader(
1495 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1496 Shader* fshader = shader_manager_.CreateShader(
1497 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1498 // Check shader got created.
1499 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1500 // Set Status
1501 TestHelper::SetShaderStates(
1502 gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
1503 NULL);
1504 // Check attrib infos got copied.
1505 for (AttributeMap::const_iterator it = attrib_map.begin();
1506 it != attrib_map.end(); ++it) {
1507 const sh::Attribute* variable_info =
1508 vshader->GetAttribInfo(it->first);
1509 ASSERT_TRUE(variable_info != NULL);
1510 EXPECT_EQ(it->second.type, variable_info->type);
1511 EXPECT_EQ(it->second.arraySize, variable_info->arraySize);
1512 EXPECT_EQ(it->second.precision, variable_info->precision);
1513 EXPECT_EQ(it->second.staticUse, variable_info->staticUse);
1514 EXPECT_EQ(it->second.name, variable_info->name);
1516 TestHelper::SetShaderStates(
1517 gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
1518 NULL);
1520 // Set up program
1521 const GLuint kClientProgramId = 6666;
1522 const GLuint kServiceProgramId = 8888;
1523 Program* program =
1524 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1525 ASSERT_TRUE(program != NULL);
1526 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1527 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1529 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1530 EXPECT_TRUE(LinkAsExpected(program, true));
1532 program->SetAttribLocationBinding(kAttrib1Name, 0);
1533 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1534 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1535 .Times(1)
1536 .RetiresOnSaturation();
1537 EXPECT_TRUE(LinkAsExpected(program, true));
1539 program->SetAttribLocationBinding("xxx", 0);
1540 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1541 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1542 .Times(1)
1543 .RetiresOnSaturation();
1544 EXPECT_TRUE(LinkAsExpected(program, true));
1546 program->SetAttribLocationBinding(kAttrib2Name, 1);
1547 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1548 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1549 .Times(2)
1550 .RetiresOnSaturation();
1551 EXPECT_TRUE(LinkAsExpected(program, true));
1553 program->SetAttribLocationBinding(kAttrib2Name, 0);
1554 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1555 EXPECT_TRUE(LinkAsExpected(program, false));
1557 program->SetAttribLocationBinding(kAttribMatName, 1);
1558 program->SetAttribLocationBinding(kAttrib2Name, 3);
1559 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1560 .Times(3)
1561 .RetiresOnSaturation();
1562 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1563 EXPECT_TRUE(LinkAsExpected(program, true));
1565 program->SetAttribLocationBinding(kAttrib2Name, 2);
1566 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1567 EXPECT_TRUE(LinkAsExpected(program, false));
1570 TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
1571 // Set up shader
1572 const GLuint kVShaderClientId = 1;
1573 const GLuint kVShaderServiceId = 11;
1574 const GLuint kFShaderClientId = 2;
1575 const GLuint kFShaderServiceId = 12;
1577 UniformMap vertex_uniform_map;
1578 vertex_uniform_map["a"] = TestHelper::ConstructUniform(
1579 GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a");
1580 UniformMap frag_uniform_map;
1581 frag_uniform_map["a"] = TestHelper::ConstructUniform(
1582 GL_FLOAT, 3, GL_LOW_FLOAT, true, "a");
1584 // Check we can create shader.
1585 Shader* vshader = shader_manager_.CreateShader(
1586 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1587 Shader* fshader = shader_manager_.CreateShader(
1588 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1589 // Check shader got created.
1590 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1591 // Set Status
1592 TestHelper::SetShaderStates(
1593 gl_.get(), vshader, true, NULL, NULL, NULL, NULL,
1594 &vertex_uniform_map, NULL, NULL);
1595 TestHelper::SetShaderStates(
1596 gl_.get(), fshader, true, NULL, NULL, NULL, NULL,
1597 &frag_uniform_map, NULL, NULL);
1599 // Set up program
1600 const GLuint kClientProgramId = 6666;
1601 const GLuint kServiceProgramId = 8888;
1602 Program* program =
1603 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1604 ASSERT_TRUE(program != NULL);
1605 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1606 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1608 std::string conflicting_name;
1610 EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1611 EXPECT_EQ("a", conflicting_name);
1612 EXPECT_TRUE(LinkAsExpected(program, false));
1615 // If a varying has different type in the vertex and fragment
1616 // shader, linking should fail.
1617 TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
1618 const VarInfo kVertexVarying =
1619 { GL_FLOAT_VEC3, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1620 const VarInfo kFragmentVarying =
1621 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1622 Program* program = SetupShaderVariableTest(
1623 &kVertexVarying, 1, &kFragmentVarying, 1);
1625 std::string conflicting_name;
1627 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1628 EXPECT_EQ("a", conflicting_name);
1629 EXPECT_TRUE(LinkAsExpected(program, false));
1632 // If a varying has different array size in the vertex and fragment
1633 // shader, linking should fail.
1634 TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
1635 const VarInfo kVertexVarying =
1636 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1637 const VarInfo kFragmentVarying =
1638 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1639 Program* program = SetupShaderVariableTest(
1640 &kVertexVarying, 1, &kFragmentVarying, 1);
1642 std::string conflicting_name;
1644 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1645 EXPECT_EQ("a", conflicting_name);
1646 EXPECT_TRUE(LinkAsExpected(program, false));
1649 // If a varying has different precision in the vertex and fragment
1650 // shader, linking should succeed.
1651 TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
1652 const VarInfo kVertexVarying =
1653 { GL_FLOAT, 2, GL_HIGH_FLOAT, true, "a", kVarVarying };
1654 const VarInfo kFragmentVarying =
1655 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1656 Program* program = SetupShaderVariableTest(
1657 &kVertexVarying, 1, &kFragmentVarying, 1);
1659 std::string conflicting_name;
1661 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1662 EXPECT_TRUE(conflicting_name.empty());
1663 EXPECT_TRUE(LinkAsExpected(program, true));
1666 // If a varying is statically used in fragment shader but not
1667 // declared in vertex shader, link should fail.
1668 TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
1669 const VarInfo kFragmentVarying =
1670 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1671 Program* program = SetupShaderVariableTest(
1672 NULL, 0, &kFragmentVarying, 1);
1674 std::string conflicting_name;
1676 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1677 EXPECT_EQ("a", conflicting_name);
1678 EXPECT_TRUE(LinkAsExpected(program, false));
1681 // If a varying is declared but not statically used in fragment
1682 // shader, even if it's not declared in vertex shader, link should
1683 // succeed.
1684 TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
1685 const VarInfo kFragmentVarying =
1686 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, false, "a", kVarVarying };
1687 Program* program = SetupShaderVariableTest(
1688 NULL, 0, &kFragmentVarying, 1);
1690 std::string conflicting_name;
1692 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1693 EXPECT_TRUE(conflicting_name.empty());
1694 EXPECT_TRUE(LinkAsExpected(program, true));
1697 // Uniforms and attributes are both global variables, thus sharing
1698 // the same namespace. Any name conflicts should cause link
1699 // failure.
1700 TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
1701 const VarInfo kVertexAttribute =
1702 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarAttribute };
1703 const VarInfo kFragmentUniform =
1704 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarUniform };
1705 Program* program = SetupShaderVariableTest(
1706 &kVertexAttribute, 1, &kFragmentUniform, 1);
1708 std::string conflicting_name;
1710 EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1711 EXPECT_EQ("a", conflicting_name);
1712 EXPECT_TRUE(LinkAsExpected(program, false));
1715 // Varyings go over 8 rows.
1716 TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
1717 const VarInfo kVertexVaryings[] = {
1718 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1719 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1721 const VarInfo kFragmentVaryings[] = {
1722 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1723 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1725 Program* program = SetupShaderVariableTest(
1726 kVertexVaryings, 2, kFragmentVaryings, 2);
1728 EXPECT_FALSE(
1729 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1730 EXPECT_TRUE(LinkAsExpected(program, false));
1733 // Varyings go over 8 rows but some are inactive
1734 TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
1735 const VarInfo kVertexVaryings[] = {
1736 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1737 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1739 const VarInfo kFragmentVaryings[] = {
1740 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1741 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1743 Program* program = SetupShaderVariableTest(
1744 kVertexVaryings, 2, kFragmentVaryings, 2);
1746 EXPECT_TRUE(
1747 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1748 EXPECT_TRUE(LinkAsExpected(program, true));
1751 // Varyings go over 8 rows but some are inactive.
1752 // However, we still fail the check if kCountAll option is used.
1753 TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
1754 const VarInfo kVertexVaryings[] = {
1755 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1756 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1758 const VarInfo kFragmentVaryings[] = {
1759 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1760 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1762 Program* program = SetupShaderVariableTest(
1763 kVertexVaryings, 2, kFragmentVaryings, 2);
1765 EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1768 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
1769 const GLuint kVShaderClientId = 2001;
1770 const GLuint kFShaderClientId = 2002;
1771 const GLuint kVShaderServiceId = 3001;
1772 const GLuint kFShaderServiceId = 3002;
1773 Shader* vshader = shader_manager_.CreateShader(
1774 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1775 ASSERT_TRUE(vshader != NULL);
1776 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1777 Shader* fshader = shader_manager_.CreateShader(
1778 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1779 ASSERT_TRUE(fshader != NULL);
1780 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1781 static const GLuint kClientProgramId = 1234;
1782 static const GLuint kServiceProgramId = 5679;
1783 Program* program = manager_.CreateProgram(
1784 kClientProgramId, kServiceProgramId);
1785 ASSERT_TRUE(program != NULL);
1786 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1787 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1789 static const GLenum kSamplerTypes[] = {
1790 GL_SAMPLER_2D,
1791 GL_SAMPLER_CUBE,
1792 GL_SAMPLER_EXTERNAL_OES,
1793 GL_SAMPLER_3D_OES,
1794 GL_SAMPLER_2D_RECT_ARB,
1796 const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
1797 for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
1798 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1799 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1800 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1801 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1803 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1804 { kUniform1Name,
1805 kUniform1Size,
1806 kUniform1Type,
1807 kUniform1FakeLocation,
1808 kUniform1RealLocation,
1809 kUniform1DesiredLocation,
1810 kUniform1Name,
1812 { kUniform2Name,
1813 kUniform2Size,
1814 kSamplerTypes[ii],
1815 kUniform2FakeLocation,
1816 kUniform2RealLocation,
1817 kUniform2DesiredLocation,
1818 kUniform2NameWithArrayIndex,
1820 { kUniform3Name,
1821 kUniform3Size,
1822 kUniform3Type,
1823 kUniform3FakeLocation,
1824 kUniform3RealLocation,
1825 kUniform3DesiredLocation,
1826 kUniform3NameWithArrayIndex,
1829 const size_t kNumAttribs = arraysize(kAttribs);
1830 const size_t kNumUniforms = arraysize(kUniforms);
1831 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1832 kServiceProgramId);
1833 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1834 base::Bind(&ShaderCacheCb));
1835 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
1836 manager_.ClearUniforms(program);
1840 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
1841 const GLuint kVShaderClientId = 2001;
1842 const GLuint kFShaderClientId = 2002;
1843 const GLuint kVShaderServiceId = 3001;
1844 const GLuint kFShaderServiceId = 3002;
1846 const GLint kUniform1DesiredLocation = 10;
1847 const GLint kUniform2DesiredLocation = -1;
1848 const GLint kUniform3DesiredLocation = 5;
1850 Shader* vshader = shader_manager_.CreateShader(
1851 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1852 ASSERT_TRUE(vshader != NULL);
1853 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1854 Shader* fshader = shader_manager_.CreateShader(
1855 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1856 ASSERT_TRUE(fshader != NULL);
1857 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1858 static const GLuint kClientProgramId = 1234;
1859 static const GLuint kServiceProgramId = 5679;
1860 Program* program = manager_.CreateProgram(
1861 kClientProgramId, kServiceProgramId);
1862 ASSERT_TRUE(program != NULL);
1863 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1864 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1865 EXPECT_TRUE(program->SetUniformLocationBinding(
1866 kUniform1Name, kUniform1DesiredLocation));
1867 EXPECT_TRUE(program->SetUniformLocationBinding(
1868 kUniform3Name, kUniform3DesiredLocation));
1870 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1871 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1872 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1873 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1875 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1876 { kUniform1Name,
1877 kUniform1Size,
1878 kUniform1Type,
1879 kUniform1FakeLocation,
1880 kUniform1RealLocation,
1881 kUniform1DesiredLocation,
1882 kUniform1Name,
1884 { kUniform2Name,
1885 kUniform2Size,
1886 kUniform2Type,
1887 kUniform2FakeLocation,
1888 kUniform2RealLocation,
1889 kUniform2DesiredLocation,
1890 kUniform2NameWithArrayIndex,
1892 { kUniform3Name,
1893 kUniform3Size,
1894 kUniform3Type,
1895 kUniform3FakeLocation,
1896 kUniform3RealLocation,
1897 kUniform3DesiredLocation,
1898 kUniform3NameWithArrayIndex,
1902 const size_t kNumAttribs = arraysize(kAttribs);
1903 const size_t kNumUniforms = arraysize(kUniforms);
1904 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1905 kServiceProgramId);
1906 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1907 base::Bind(&ShaderCacheCb));
1909 EXPECT_EQ(kUniform1DesiredLocation,
1910 program->GetUniformFakeLocation(kUniform1Name));
1911 EXPECT_EQ(kUniform3DesiredLocation,
1912 program->GetUniformFakeLocation(kUniform3Name));
1913 EXPECT_EQ(kUniform3DesiredLocation,
1914 program->GetUniformFakeLocation(kUniform3NameWithArrayIndex));
1917 class ProgramManagerWithCacheTest : public GpuServiceTest {
1918 public:
1919 static const GLuint kClientProgramId = 1;
1920 static const GLuint kServiceProgramId = 10;
1921 static const GLuint kVertexShaderClientId = 2;
1922 static const GLuint kFragmentShaderClientId = 20;
1923 static const GLuint kVertexShaderServiceId = 3;
1924 static const GLuint kFragmentShaderServiceId = 30;
1926 ProgramManagerWithCacheTest()
1927 : cache_(new MockProgramCache()),
1928 manager_(cache_.get(), kMaxVaryingVectors),
1929 vertex_shader_(NULL),
1930 fragment_shader_(NULL),
1931 program_(NULL) {
1933 ~ProgramManagerWithCacheTest() override {
1934 manager_.Destroy(false);
1935 shader_manager_.Destroy(false);
1938 protected:
1939 void SetUp() override {
1940 GpuServiceTest::SetUp();
1942 vertex_shader_ = shader_manager_.CreateShader(
1943 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
1944 fragment_shader_ = shader_manager_.CreateShader(
1945 kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
1946 ASSERT_TRUE(vertex_shader_ != NULL);
1947 ASSERT_TRUE(fragment_shader_ != NULL);
1948 vertex_shader_->set_source("lka asjf bjajsdfj");
1949 fragment_shader_->set_source("lka asjf a fasgag 3rdsf3 bjajsdfj");
1951 program_ = manager_.CreateProgram(
1952 kClientProgramId, kServiceProgramId);
1953 ASSERT_TRUE(program_ != NULL);
1955 program_->AttachShader(&shader_manager_, vertex_shader_);
1956 program_->AttachShader(&shader_manager_, fragment_shader_);
1959 void SetShadersCompiled() {
1960 TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
1961 TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
1964 void SetProgramCached() {
1965 cache_->LinkedProgramCacheSuccess(
1966 vertex_shader_->source(),
1967 fragment_shader_->source(),
1968 &program_->bind_attrib_location_map(),
1969 program_->transform_feedback_varyings(),
1970 program_->transform_feedback_buffer_mode());
1973 void SetExpectationsForProgramCached() {
1974 SetExpectationsForProgramCached(program_,
1975 vertex_shader_,
1976 fragment_shader_);
1979 void SetExpectationsForProgramCached(
1980 Program* program,
1981 Shader* vertex_shader,
1982 Shader* fragment_shader) {
1983 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1984 program->service_id(),
1985 vertex_shader,
1986 fragment_shader,
1987 &program->bind_attrib_location_map(),
1988 program_->transform_feedback_varyings(),
1989 program_->transform_feedback_buffer_mode(),
1990 _)).Times(1);
1993 void SetExpectationsForNotCachingProgram() {
1994 SetExpectationsForNotCachingProgram(program_,
1995 vertex_shader_,
1996 fragment_shader_);
1999 void SetExpectationsForNotCachingProgram(
2000 Program* program,
2001 Shader* vertex_shader,
2002 Shader* fragment_shader) {
2003 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
2004 program->service_id(),
2005 vertex_shader,
2006 fragment_shader,
2007 &program->bind_attrib_location_map(),
2008 program_->transform_feedback_varyings(),
2009 program_->transform_feedback_buffer_mode(),
2010 _)).Times(0);
2013 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
2014 SetExpectationsForProgramLoad(kServiceProgramId,
2015 program_,
2016 vertex_shader_,
2017 fragment_shader_,
2018 result);
2021 void SetExpectationsForProgramLoad(
2022 GLuint service_program_id,
2023 Program* program,
2024 Shader* vertex_shader,
2025 Shader* fragment_shader,
2026 ProgramCache::ProgramLoadResult result) {
2027 EXPECT_CALL(*cache_.get(),
2028 LoadLinkedProgram(service_program_id,
2029 vertex_shader,
2030 fragment_shader,
2031 &program->bind_attrib_location_map(),
2032 program_->transform_feedback_varyings(),
2033 program_->transform_feedback_buffer_mode(),
2035 .WillOnce(Return(result));
2038 void SetExpectationsForProgramLoadSuccess() {
2039 SetExpectationsForProgramLoadSuccess(kServiceProgramId);
2042 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
2043 TestHelper::SetupProgramSuccessExpectations(gl_.get(),
2044 NULL,
2046 NULL,
2048 service_program_id);
2051 void SetExpectationsForProgramLink() {
2052 SetExpectationsForProgramLink(kServiceProgramId);
2055 void SetExpectationsForProgramLink(GLuint service_program_id) {
2056 TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
2057 if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
2058 EXPECT_CALL(*gl_.get(),
2059 ProgramParameteri(service_program_id,
2060 PROGRAM_BINARY_RETRIEVABLE_HINT,
2061 GL_TRUE)).Times(1);
2065 void SetExpectationsForSuccessCompile(
2066 const Shader* shader) {
2067 const GLuint shader_id = shader->service_id();
2068 const char* src = shader->source().c_str();
2069 EXPECT_CALL(*gl_.get(),
2070 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2071 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2072 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2073 .WillOnce(SetArgPointee<2>(GL_TRUE));
2076 void SetExpectationsForNoCompile(const Shader* shader) {
2077 const GLuint shader_id = shader->service_id();
2078 const char* src = shader->source().c_str();
2079 EXPECT_CALL(*gl_.get(),
2080 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
2081 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
2082 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2083 .Times(0);
2086 void SetExpectationsForErrorCompile(const Shader* shader) {
2087 const GLuint shader_id = shader->service_id();
2088 const char* src = shader->source().c_str();
2089 EXPECT_CALL(*gl_.get(),
2090 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2091 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2092 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2093 .WillOnce(SetArgPointee<2>(GL_FALSE));
2094 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
2095 .WillOnce(SetArgPointee<2>(0));
2096 EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
2097 .Times(1);
2100 scoped_ptr<MockProgramCache> cache_;
2101 ProgramManager manager_;
2103 Shader* vertex_shader_;
2104 Shader* fragment_shader_;
2105 Program* program_;
2106 ShaderManager shader_manager_;
2109 // GCC requires these declarations, but MSVC requires they not be present
2110 #ifndef COMPILER_MSVC
2111 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
2112 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
2113 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
2114 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
2115 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
2116 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
2117 #endif
2119 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
2120 SetShadersCompiled();
2121 SetExpectationsForProgramLink();
2122 SetExpectationsForProgramCached();
2123 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2124 base::Bind(&ShaderCacheCb)));
2127 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
2128 SetShadersCompiled();
2129 SetProgramCached();
2131 SetExpectationsForNoCompile(vertex_shader_);
2132 SetExpectationsForNoCompile(fragment_shader_);
2133 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
2134 SetExpectationsForNotCachingProgram();
2135 SetExpectationsForProgramLoadSuccess();
2137 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2138 base::Bind(&ShaderCacheCb)));
2141 } // namespace gles2
2142 } // namespace gpu