Roll src/third_party/skia d32087a:1052f51
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blobedbdbf181fe7f9b1b89887800117237b7f739899
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,
1242 GL_TRANSFORM_FEEDBACK_BUFFER_MODE,
1244 .WillOnce(SetArgPointee<2>(GL_INTERLEAVED_ATTRIBS))
1245 .RetiresOnSaturation();
1246 EXPECT_CALL(*(gl_.get()),
1247 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1248 .WillOnce(SetArgPointee<2>(GL_FALSE))
1249 .RetiresOnSaturation();
1250 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1251 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1252 TransformFeedbackVaryingsHeader* header =
1253 bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1254 0, sizeof(TransformFeedbackVaryingsHeader));
1255 EXPECT_TRUE(header != NULL);
1256 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1257 EXPECT_EQ(static_cast<uint32_t>(GL_INTERLEAVED_ATTRIBS),
1258 header->transform_feedback_buffer_mode);
1259 // Zero transform feedback blocks.
1260 EXPECT_CALL(*(gl_.get()),
1261 GetProgramiv(kServiceProgramId,
1262 GL_TRANSFORM_FEEDBACK_BUFFER_MODE,
1264 .WillOnce(SetArgPointee<2>(GL_SEPARATE_ATTRIBS))
1265 .RetiresOnSaturation();
1266 EXPECT_CALL(*(gl_.get()),
1267 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1268 .WillOnce(SetArgPointee<2>(GL_TRUE))
1269 .RetiresOnSaturation();
1270 EXPECT_CALL(*(gl_.get()),
1271 GetProgramiv(
1272 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1273 .WillOnce(SetArgPointee<2>(0))
1274 .RetiresOnSaturation();
1275 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1276 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1277 header = bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1278 0, sizeof(TransformFeedbackVaryingsHeader));
1279 EXPECT_TRUE(header != NULL);
1280 EXPECT_EQ(static_cast<uint32_t>(GL_SEPARATE_ATTRIBS),
1281 header->transform_feedback_buffer_mode);
1282 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1285 TEST_F(ProgramManagerWithShaderTest,
1286 ProgramInfoGetTransformFeedbackVaryingsValid) {
1287 CommonDecoder::Bucket bucket;
1288 const Program* program = manager_.GetProgram(kClientProgramId);
1289 ASSERT_TRUE(program != NULL);
1290 struct Data {
1291 TransformFeedbackVaryingsHeader header;
1292 TransformFeedbackVaryingInfo entry[2];
1293 char name0[4];
1294 char name1[8];
1296 Data data;
1297 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1298 // This is a testing only problem.
1299 const char* kName[] = { "cow", "chicken" };
1300 data.header.transform_feedback_buffer_mode = GL_INTERLEAVED_ATTRIBS;
1301 data.header.num_transform_feedback_varyings = 2;
1302 data.entry[0].size = 1;
1303 data.entry[0].type = GL_FLOAT_VEC2;
1304 data.entry[0].name_offset = ComputeOffset(&data, data.name0);
1305 data.entry[0].name_length = arraysize(data.name0);
1306 data.entry[1].size = 2;
1307 data.entry[1].type = GL_FLOAT;
1308 data.entry[1].name_offset = ComputeOffset(&data, data.name1);
1309 data.entry[1].name_length = arraysize(data.name1);
1310 memcpy(data.name0, kName[0], arraysize(data.name0));
1311 memcpy(data.name1, kName[1], arraysize(data.name1));
1314 EXPECT_CALL(*(gl_.get()),
1315 GetProgramiv(kServiceProgramId,
1316 GL_TRANSFORM_FEEDBACK_BUFFER_MODE,
1318 .WillOnce(SetArgPointee<2>(GL_INTERLEAVED_ATTRIBS))
1319 .RetiresOnSaturation();
1320 EXPECT_CALL(*(gl_.get()),
1321 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1322 .WillOnce(SetArgPointee<2>(GL_TRUE))
1323 .RetiresOnSaturation();
1324 EXPECT_CALL(*(gl_.get()),
1325 GetProgramiv(
1326 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1327 .WillOnce(SetArgPointee<2>(data.header.num_transform_feedback_varyings))
1328 .RetiresOnSaturation();
1329 GLsizei max_length = 1 + std::max(strlen(kName[0]), strlen(kName[1]));
1330 EXPECT_CALL(*(gl_.get()),
1331 GetProgramiv(kServiceProgramId,
1332 GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _))
1333 .WillOnce(SetArgPointee<2>(max_length))
1334 .RetiresOnSaturation();
1335 for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings;
1336 ++ii) {
1337 EXPECT_CALL(*(gl_.get()),
1338 GetTransformFeedbackVarying(
1339 kServiceProgramId, ii, max_length, _, _, _, _))
1340 .WillOnce(DoAll(
1341 SetArgPointee<3>(data.entry[ii].name_length - 1),
1342 SetArgPointee<4>(data.entry[ii].size),
1343 SetArgPointee<5>(data.entry[ii].type),
1344 SetArrayArgument<6>(
1345 kName[ii], kName[ii] + data.entry[ii].name_length)))
1346 .RetiresOnSaturation();
1348 program->GetTransformFeedbackVaryings(&bucket);
1349 EXPECT_EQ(sizeof(Data), bucket.size());
1350 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1351 EXPECT_TRUE(bucket_data != NULL);
1352 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1355 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3None) {
1356 CommonDecoder::Bucket bucket;
1357 const Program* program = manager_.GetProgram(kClientProgramId);
1358 ASSERT_TRUE(program != NULL);
1359 // The program's previous link failed.
1360 EXPECT_CALL(*(gl_.get()),
1361 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1362 .WillOnce(SetArgPointee<2>(GL_FALSE))
1363 .RetiresOnSaturation();
1364 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1365 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1366 UniformsES3Header* header =
1367 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1368 EXPECT_TRUE(header != NULL);
1369 EXPECT_EQ(0u, header->num_uniforms);
1370 // Zero uniform blocks.
1371 EXPECT_CALL(*(gl_.get()),
1372 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1373 .WillOnce(SetArgPointee<2>(GL_TRUE))
1374 .RetiresOnSaturation();
1375 EXPECT_CALL(*(gl_.get()),
1376 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1377 .WillOnce(SetArgPointee<2>(0))
1378 .RetiresOnSaturation();
1379 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1380 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1381 header =
1382 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1383 EXPECT_TRUE(header != NULL);
1384 EXPECT_EQ(0u, header->num_uniforms);
1387 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3Valid) {
1388 CommonDecoder::Bucket bucket;
1389 const Program* program = manager_.GetProgram(kClientProgramId);
1390 ASSERT_TRUE(program != NULL);
1391 struct Data {
1392 UniformsES3Header header;
1393 UniformES3Info entry[2];
1395 Data data;
1396 const GLint kBlockIndex[] = { -1, 2 };
1397 const GLint kOffset[] = { 3, 4 };
1398 const GLint kArrayStride[] = { 7, 8 };
1399 const GLint kMatrixStride[] = { 9, 10 };
1400 const GLint kIsRowMajor[] = { 0, 1 };
1401 data.header.num_uniforms = 2;
1402 for (uint32_t ii = 0; ii < data.header.num_uniforms; ++ii) {
1403 data.entry[ii].block_index = kBlockIndex[ii];
1404 data.entry[ii].offset = kOffset[ii];
1405 data.entry[ii].array_stride = kArrayStride[ii];
1406 data.entry[ii].matrix_stride = kMatrixStride[ii];
1407 data.entry[ii].is_row_major = kIsRowMajor[ii];
1410 EXPECT_CALL(*(gl_.get()),
1411 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1412 .WillOnce(SetArgPointee<2>(GL_TRUE))
1413 .RetiresOnSaturation();
1414 EXPECT_CALL(*(gl_.get()),
1415 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1416 .WillOnce(SetArgPointee<2>(data.header.num_uniforms))
1417 .RetiresOnSaturation();
1419 const GLenum kPname[] = {
1420 GL_UNIFORM_BLOCK_INDEX,
1421 GL_UNIFORM_OFFSET,
1422 GL_UNIFORM_ARRAY_STRIDE,
1423 GL_UNIFORM_MATRIX_STRIDE,
1424 GL_UNIFORM_IS_ROW_MAJOR,
1426 const GLint* kParams[] = {
1427 kBlockIndex,
1428 kOffset,
1429 kArrayStride,
1430 kMatrixStride,
1431 kIsRowMajor,
1433 const size_t kNumIterations = arraysize(kPname);
1434 for (size_t ii = 0; ii < kNumIterations; ++ii) {
1435 EXPECT_CALL(*(gl_.get()),
1436 GetActiveUniformsiv(
1437 kServiceProgramId, data.header.num_uniforms, _,
1438 kPname[ii], _))
1439 .WillOnce(SetArrayArgument<4>(
1440 kParams[ii], kParams[ii] + data.header.num_uniforms))
1441 .RetiresOnSaturation();
1444 program->GetUniformsES3(&bucket);
1445 EXPECT_EQ(sizeof(Data), bucket.size());
1446 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1447 EXPECT_TRUE(bucket_data != NULL);
1448 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1451 // Some drivers optimize out unused uniform array elements, so their
1452 // location would be -1.
1453 TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
1454 CommonDecoder::Bucket bucket;
1455 const Program* program = manager_.GetProgram(kClientProgramId);
1456 ASSERT_TRUE(program != NULL);
1457 // Emulate the situation that only the first element has a valid location.
1458 // TODO(zmo): Don't assume these are in order.
1459 for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
1460 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
1461 program->GetUniformInfo(ii));
1462 ASSERT_TRUE(uniform != NULL);
1463 EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
1464 uniform->element_locations.size());
1465 for (GLsizei jj = 1; jj < uniform->size; ++jj)
1466 uniform->element_locations[jj] = -1;
1468 program->GetProgramInfo(&manager_, &bucket);
1469 ProgramInfoHeader* header =
1470 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1471 ASSERT_TRUE(header != NULL);
1472 EXPECT_EQ(1u, header->link_status);
1473 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1474 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1475 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1476 sizeof(*header),
1477 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1478 ASSERT_TRUE(inputs != NULL);
1479 const ProgramInput* input = inputs + header->num_attribs;
1480 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1481 const UniformInfo& expected = kUniforms[ii];
1482 EXPECT_EQ(expected.size, input->size);
1483 const int32* locations = bucket.GetDataAs<const int32*>(
1484 input->location_offset, sizeof(int32) * input->size);
1485 ASSERT_TRUE(locations != NULL);
1486 EXPECT_EQ(
1487 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1488 locations[0]);
1489 for (int32 jj = 1; jj < input->size; ++jj)
1490 EXPECT_EQ(-1, locations[jj]);
1491 ++input;
1495 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1496 // Set up shader
1497 const GLuint kVShaderClientId = 1;
1498 const GLuint kVShaderServiceId = 11;
1499 const GLuint kFShaderClientId = 2;
1500 const GLuint kFShaderServiceId = 12;
1501 AttributeMap attrib_map;
1502 for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
1503 attrib_map[kAttribs[ii].name] = TestHelper::ConstructAttribute(
1504 kAttribs[ii].type,
1505 kAttribs[ii].size,
1506 GL_MEDIUM_FLOAT,
1507 kAttribStaticUse,
1508 kAttribs[ii].name);
1510 const char kAttribMatName[] = "matAttrib";
1511 attrib_map[kAttribMatName] = TestHelper::ConstructAttribute(
1512 GL_FLOAT_MAT2,
1514 GL_MEDIUM_FLOAT,
1515 kAttribStaticUse,
1516 kAttribMatName);
1517 // Check we can create shader.
1518 Shader* vshader = shader_manager_.CreateShader(
1519 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1520 Shader* fshader = shader_manager_.CreateShader(
1521 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1522 // Check shader got created.
1523 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1524 // Set Status
1525 TestHelper::SetShaderStates(
1526 gl_.get(), vshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
1527 NULL);
1528 // Check attrib infos got copied.
1529 for (AttributeMap::const_iterator it = attrib_map.begin();
1530 it != attrib_map.end(); ++it) {
1531 const sh::Attribute* variable_info =
1532 vshader->GetAttribInfo(it->first);
1533 ASSERT_TRUE(variable_info != NULL);
1534 EXPECT_EQ(it->second.type, variable_info->type);
1535 EXPECT_EQ(it->second.arraySize, variable_info->arraySize);
1536 EXPECT_EQ(it->second.precision, variable_info->precision);
1537 EXPECT_EQ(it->second.staticUse, variable_info->staticUse);
1538 EXPECT_EQ(it->second.name, variable_info->name);
1540 TestHelper::SetShaderStates(
1541 gl_.get(), fshader, true, NULL, NULL, NULL, &attrib_map, NULL, NULL,
1542 NULL);
1544 // Set up program
1545 const GLuint kClientProgramId = 6666;
1546 const GLuint kServiceProgramId = 8888;
1547 Program* program =
1548 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1549 ASSERT_TRUE(program != NULL);
1550 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1551 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1553 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1554 EXPECT_TRUE(LinkAsExpected(program, true));
1556 program->SetAttribLocationBinding(kAttrib1Name, 0);
1557 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1558 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1559 .Times(1)
1560 .RetiresOnSaturation();
1561 EXPECT_TRUE(LinkAsExpected(program, true));
1563 program->SetAttribLocationBinding("xxx", 0);
1564 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1565 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1566 .Times(1)
1567 .RetiresOnSaturation();
1568 EXPECT_TRUE(LinkAsExpected(program, true));
1570 program->SetAttribLocationBinding(kAttrib2Name, 1);
1571 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1572 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1573 .Times(2)
1574 .RetiresOnSaturation();
1575 EXPECT_TRUE(LinkAsExpected(program, true));
1577 program->SetAttribLocationBinding(kAttrib2Name, 0);
1578 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1579 EXPECT_TRUE(LinkAsExpected(program, false));
1581 program->SetAttribLocationBinding(kAttribMatName, 1);
1582 program->SetAttribLocationBinding(kAttrib2Name, 3);
1583 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1584 .Times(3)
1585 .RetiresOnSaturation();
1586 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1587 EXPECT_TRUE(LinkAsExpected(program, true));
1589 program->SetAttribLocationBinding(kAttrib2Name, 2);
1590 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1591 EXPECT_TRUE(LinkAsExpected(program, false));
1594 TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
1595 // Set up shader
1596 const GLuint kVShaderClientId = 1;
1597 const GLuint kVShaderServiceId = 11;
1598 const GLuint kFShaderClientId = 2;
1599 const GLuint kFShaderServiceId = 12;
1601 UniformMap vertex_uniform_map;
1602 vertex_uniform_map["a"] = TestHelper::ConstructUniform(
1603 GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a");
1604 UniformMap frag_uniform_map;
1605 frag_uniform_map["a"] = TestHelper::ConstructUniform(
1606 GL_FLOAT, 3, GL_LOW_FLOAT, true, "a");
1608 // Check we can create shader.
1609 Shader* vshader = shader_manager_.CreateShader(
1610 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1611 Shader* fshader = shader_manager_.CreateShader(
1612 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1613 // Check shader got created.
1614 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1615 // Set Status
1616 TestHelper::SetShaderStates(
1617 gl_.get(), vshader, true, NULL, NULL, NULL, NULL,
1618 &vertex_uniform_map, NULL, NULL);
1619 TestHelper::SetShaderStates(
1620 gl_.get(), fshader, true, NULL, NULL, NULL, NULL,
1621 &frag_uniform_map, NULL, NULL);
1623 // Set up program
1624 const GLuint kClientProgramId = 6666;
1625 const GLuint kServiceProgramId = 8888;
1626 Program* program =
1627 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1628 ASSERT_TRUE(program != NULL);
1629 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1630 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1632 std::string conflicting_name;
1634 EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1635 EXPECT_EQ("a", conflicting_name);
1636 EXPECT_TRUE(LinkAsExpected(program, false));
1639 // If a varying has different type in the vertex and fragment
1640 // shader, linking should fail.
1641 TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
1642 const VarInfo kVertexVarying =
1643 { GL_FLOAT_VEC3, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1644 const VarInfo kFragmentVarying =
1645 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1646 Program* program = SetupShaderVariableTest(
1647 &kVertexVarying, 1, &kFragmentVarying, 1);
1649 std::string conflicting_name;
1651 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1652 EXPECT_EQ("a", conflicting_name);
1653 EXPECT_TRUE(LinkAsExpected(program, false));
1656 // If a varying has different array size in the vertex and fragment
1657 // shader, linking should fail.
1658 TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
1659 const VarInfo kVertexVarying =
1660 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1661 const VarInfo kFragmentVarying =
1662 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1663 Program* program = SetupShaderVariableTest(
1664 &kVertexVarying, 1, &kFragmentVarying, 1);
1666 std::string conflicting_name;
1668 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1669 EXPECT_EQ("a", conflicting_name);
1670 EXPECT_TRUE(LinkAsExpected(program, false));
1673 // If a varying has different precision in the vertex and fragment
1674 // shader, linking should succeed.
1675 TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
1676 const VarInfo kVertexVarying =
1677 { GL_FLOAT, 2, GL_HIGH_FLOAT, true, "a", kVarVarying };
1678 const VarInfo kFragmentVarying =
1679 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1680 Program* program = SetupShaderVariableTest(
1681 &kVertexVarying, 1, &kFragmentVarying, 1);
1683 std::string conflicting_name;
1685 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1686 EXPECT_TRUE(conflicting_name.empty());
1687 EXPECT_TRUE(LinkAsExpected(program, true));
1690 // If a varying is statically used in fragment shader but not
1691 // declared in vertex shader, link should fail.
1692 TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
1693 const VarInfo kFragmentVarying =
1694 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1695 Program* program = SetupShaderVariableTest(
1696 NULL, 0, &kFragmentVarying, 1);
1698 std::string conflicting_name;
1700 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1701 EXPECT_EQ("a", conflicting_name);
1702 EXPECT_TRUE(LinkAsExpected(program, false));
1705 // If a varying is declared but not statically used in fragment
1706 // shader, even if it's not declared in vertex shader, link should
1707 // succeed.
1708 TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
1709 const VarInfo kFragmentVarying =
1710 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, false, "a", kVarVarying };
1711 Program* program = SetupShaderVariableTest(
1712 NULL, 0, &kFragmentVarying, 1);
1714 std::string conflicting_name;
1716 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1717 EXPECT_TRUE(conflicting_name.empty());
1718 EXPECT_TRUE(LinkAsExpected(program, true));
1721 // Uniforms and attributes are both global variables, thus sharing
1722 // the same namespace. Any name conflicts should cause link
1723 // failure.
1724 TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
1725 const VarInfo kVertexAttribute =
1726 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarAttribute };
1727 const VarInfo kFragmentUniform =
1728 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarUniform };
1729 Program* program = SetupShaderVariableTest(
1730 &kVertexAttribute, 1, &kFragmentUniform, 1);
1732 std::string conflicting_name;
1734 EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1735 EXPECT_EQ("a", conflicting_name);
1736 EXPECT_TRUE(LinkAsExpected(program, false));
1739 // Varyings go over 8 rows.
1740 TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
1741 const VarInfo kVertexVaryings[] = {
1742 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1743 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1745 const VarInfo kFragmentVaryings[] = {
1746 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1747 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1749 Program* program = SetupShaderVariableTest(
1750 kVertexVaryings, 2, kFragmentVaryings, 2);
1752 EXPECT_FALSE(
1753 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1754 EXPECT_TRUE(LinkAsExpected(program, false));
1757 // Varyings go over 8 rows but some are inactive
1758 TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
1759 const VarInfo kVertexVaryings[] = {
1760 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1761 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1763 const VarInfo kFragmentVaryings[] = {
1764 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1765 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1767 Program* program = SetupShaderVariableTest(
1768 kVertexVaryings, 2, kFragmentVaryings, 2);
1770 EXPECT_TRUE(
1771 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1772 EXPECT_TRUE(LinkAsExpected(program, true));
1775 // Varyings go over 8 rows but some are inactive.
1776 // However, we still fail the check if kCountAll option is used.
1777 TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
1778 const VarInfo kVertexVaryings[] = {
1779 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1780 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1782 const VarInfo kFragmentVaryings[] = {
1783 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1784 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1786 Program* program = SetupShaderVariableTest(
1787 kVertexVaryings, 2, kFragmentVaryings, 2);
1789 EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1792 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
1793 const GLuint kVShaderClientId = 2001;
1794 const GLuint kFShaderClientId = 2002;
1795 const GLuint kVShaderServiceId = 3001;
1796 const GLuint kFShaderServiceId = 3002;
1797 Shader* vshader = shader_manager_.CreateShader(
1798 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1799 ASSERT_TRUE(vshader != NULL);
1800 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1801 Shader* fshader = shader_manager_.CreateShader(
1802 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1803 ASSERT_TRUE(fshader != NULL);
1804 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1805 static const GLuint kClientProgramId = 1234;
1806 static const GLuint kServiceProgramId = 5679;
1807 Program* program = manager_.CreateProgram(
1808 kClientProgramId, kServiceProgramId);
1809 ASSERT_TRUE(program != NULL);
1810 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1811 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1813 static const GLenum kSamplerTypes[] = {
1814 GL_SAMPLER_2D,
1815 GL_SAMPLER_CUBE,
1816 GL_SAMPLER_EXTERNAL_OES,
1817 GL_SAMPLER_3D_OES,
1818 GL_SAMPLER_2D_RECT_ARB,
1820 const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
1821 for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
1822 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1823 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1824 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1825 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1827 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1828 { kUniform1Name,
1829 kUniform1Size,
1830 kUniform1Type,
1831 kUniform1FakeLocation,
1832 kUniform1RealLocation,
1833 kUniform1DesiredLocation,
1834 kUniform1Name,
1836 { kUniform2Name,
1837 kUniform2Size,
1838 kSamplerTypes[ii],
1839 kUniform2FakeLocation,
1840 kUniform2RealLocation,
1841 kUniform2DesiredLocation,
1842 kUniform2NameWithArrayIndex,
1844 { kUniform3Name,
1845 kUniform3Size,
1846 kUniform3Type,
1847 kUniform3FakeLocation,
1848 kUniform3RealLocation,
1849 kUniform3DesiredLocation,
1850 kUniform3NameWithArrayIndex,
1853 const size_t kNumAttribs = arraysize(kAttribs);
1854 const size_t kNumUniforms = arraysize(kUniforms);
1855 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1856 kServiceProgramId);
1857 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1858 base::Bind(&ShaderCacheCb));
1859 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
1860 manager_.ClearUniforms(program);
1864 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
1865 const GLuint kVShaderClientId = 2001;
1866 const GLuint kFShaderClientId = 2002;
1867 const GLuint kVShaderServiceId = 3001;
1868 const GLuint kFShaderServiceId = 3002;
1870 const GLint kUniform1DesiredLocation = 10;
1871 const GLint kUniform2DesiredLocation = -1;
1872 const GLint kUniform3DesiredLocation = 5;
1874 Shader* vshader = shader_manager_.CreateShader(
1875 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1876 ASSERT_TRUE(vshader != NULL);
1877 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1878 Shader* fshader = shader_manager_.CreateShader(
1879 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1880 ASSERT_TRUE(fshader != NULL);
1881 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1882 static const GLuint kClientProgramId = 1234;
1883 static const GLuint kServiceProgramId = 5679;
1884 Program* program = manager_.CreateProgram(
1885 kClientProgramId, kServiceProgramId);
1886 ASSERT_TRUE(program != NULL);
1887 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1888 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1889 EXPECT_TRUE(program->SetUniformLocationBinding(
1890 kUniform1Name, kUniform1DesiredLocation));
1891 EXPECT_TRUE(program->SetUniformLocationBinding(
1892 kUniform3Name, kUniform3DesiredLocation));
1894 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1895 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1896 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1897 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1899 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1900 { kUniform1Name,
1901 kUniform1Size,
1902 kUniform1Type,
1903 kUniform1FakeLocation,
1904 kUniform1RealLocation,
1905 kUniform1DesiredLocation,
1906 kUniform1Name,
1908 { kUniform2Name,
1909 kUniform2Size,
1910 kUniform2Type,
1911 kUniform2FakeLocation,
1912 kUniform2RealLocation,
1913 kUniform2DesiredLocation,
1914 kUniform2NameWithArrayIndex,
1916 { kUniform3Name,
1917 kUniform3Size,
1918 kUniform3Type,
1919 kUniform3FakeLocation,
1920 kUniform3RealLocation,
1921 kUniform3DesiredLocation,
1922 kUniform3NameWithArrayIndex,
1926 const size_t kNumAttribs = arraysize(kAttribs);
1927 const size_t kNumUniforms = arraysize(kUniforms);
1928 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1929 kServiceProgramId);
1930 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1931 base::Bind(&ShaderCacheCb));
1933 EXPECT_EQ(kUniform1DesiredLocation,
1934 program->GetUniformFakeLocation(kUniform1Name));
1935 EXPECT_EQ(kUniform3DesiredLocation,
1936 program->GetUniformFakeLocation(kUniform3Name));
1937 EXPECT_EQ(kUniform3DesiredLocation,
1938 program->GetUniformFakeLocation(kUniform3NameWithArrayIndex));
1941 class ProgramManagerWithCacheTest : public GpuServiceTest {
1942 public:
1943 static const GLuint kClientProgramId = 1;
1944 static const GLuint kServiceProgramId = 10;
1945 static const GLuint kVertexShaderClientId = 2;
1946 static const GLuint kFragmentShaderClientId = 20;
1947 static const GLuint kVertexShaderServiceId = 3;
1948 static const GLuint kFragmentShaderServiceId = 30;
1950 ProgramManagerWithCacheTest()
1951 : cache_(new MockProgramCache()),
1952 manager_(cache_.get(), kMaxVaryingVectors),
1953 vertex_shader_(NULL),
1954 fragment_shader_(NULL),
1955 program_(NULL) {
1957 ~ProgramManagerWithCacheTest() override {
1958 manager_.Destroy(false);
1959 shader_manager_.Destroy(false);
1962 protected:
1963 void SetUp() override {
1964 GpuServiceTest::SetUp();
1966 vertex_shader_ = shader_manager_.CreateShader(
1967 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
1968 fragment_shader_ = shader_manager_.CreateShader(
1969 kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
1970 ASSERT_TRUE(vertex_shader_ != NULL);
1971 ASSERT_TRUE(fragment_shader_ != NULL);
1972 vertex_shader_->set_source("lka asjf bjajsdfj");
1973 fragment_shader_->set_source("lka asjf a fasgag 3rdsf3 bjajsdfj");
1975 program_ = manager_.CreateProgram(
1976 kClientProgramId, kServiceProgramId);
1977 ASSERT_TRUE(program_ != NULL);
1979 program_->AttachShader(&shader_manager_, vertex_shader_);
1980 program_->AttachShader(&shader_manager_, fragment_shader_);
1983 void SetShadersCompiled() {
1984 TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
1985 TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
1988 void SetProgramCached() {
1989 cache_->LinkedProgramCacheSuccess(
1990 vertex_shader_->source(),
1991 fragment_shader_->source(),
1992 &program_->bind_attrib_location_map(),
1993 program_->transform_feedback_varyings(),
1994 program_->transform_feedback_buffer_mode());
1997 void SetExpectationsForProgramCached() {
1998 SetExpectationsForProgramCached(program_,
1999 vertex_shader_,
2000 fragment_shader_);
2003 void SetExpectationsForProgramCached(
2004 Program* program,
2005 Shader* vertex_shader,
2006 Shader* fragment_shader) {
2007 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
2008 program->service_id(),
2009 vertex_shader,
2010 fragment_shader,
2011 &program->bind_attrib_location_map(),
2012 program_->transform_feedback_varyings(),
2013 program_->transform_feedback_buffer_mode(),
2014 _)).Times(1);
2017 void SetExpectationsForNotCachingProgram() {
2018 SetExpectationsForNotCachingProgram(program_,
2019 vertex_shader_,
2020 fragment_shader_);
2023 void SetExpectationsForNotCachingProgram(
2024 Program* program,
2025 Shader* vertex_shader,
2026 Shader* fragment_shader) {
2027 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
2028 program->service_id(),
2029 vertex_shader,
2030 fragment_shader,
2031 &program->bind_attrib_location_map(),
2032 program_->transform_feedback_varyings(),
2033 program_->transform_feedback_buffer_mode(),
2034 _)).Times(0);
2037 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
2038 SetExpectationsForProgramLoad(kServiceProgramId,
2039 program_,
2040 vertex_shader_,
2041 fragment_shader_,
2042 result);
2045 void SetExpectationsForProgramLoad(
2046 GLuint service_program_id,
2047 Program* program,
2048 Shader* vertex_shader,
2049 Shader* fragment_shader,
2050 ProgramCache::ProgramLoadResult result) {
2051 EXPECT_CALL(*cache_.get(),
2052 LoadLinkedProgram(service_program_id,
2053 vertex_shader,
2054 fragment_shader,
2055 &program->bind_attrib_location_map(),
2056 program_->transform_feedback_varyings(),
2057 program_->transform_feedback_buffer_mode(),
2059 .WillOnce(Return(result));
2062 void SetExpectationsForProgramLoadSuccess() {
2063 SetExpectationsForProgramLoadSuccess(kServiceProgramId);
2066 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
2067 TestHelper::SetupProgramSuccessExpectations(gl_.get(),
2068 NULL,
2070 NULL,
2072 service_program_id);
2075 void SetExpectationsForProgramLink() {
2076 SetExpectationsForProgramLink(kServiceProgramId);
2079 void SetExpectationsForProgramLink(GLuint service_program_id) {
2080 TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
2081 if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
2082 EXPECT_CALL(*gl_.get(),
2083 ProgramParameteri(service_program_id,
2084 PROGRAM_BINARY_RETRIEVABLE_HINT,
2085 GL_TRUE)).Times(1);
2089 void SetExpectationsForSuccessCompile(
2090 const Shader* shader) {
2091 const GLuint shader_id = shader->service_id();
2092 const char* src = shader->source().c_str();
2093 EXPECT_CALL(*gl_.get(),
2094 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2095 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2096 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2097 .WillOnce(SetArgPointee<2>(GL_TRUE));
2100 void SetExpectationsForNoCompile(const Shader* shader) {
2101 const GLuint shader_id = shader->service_id();
2102 const char* src = shader->source().c_str();
2103 EXPECT_CALL(*gl_.get(),
2104 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
2105 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
2106 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2107 .Times(0);
2110 void SetExpectationsForErrorCompile(const Shader* shader) {
2111 const GLuint shader_id = shader->service_id();
2112 const char* src = shader->source().c_str();
2113 EXPECT_CALL(*gl_.get(),
2114 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2115 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2116 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2117 .WillOnce(SetArgPointee<2>(GL_FALSE));
2118 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
2119 .WillOnce(SetArgPointee<2>(0));
2120 EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
2121 .Times(1);
2124 scoped_ptr<MockProgramCache> cache_;
2125 ProgramManager manager_;
2127 Shader* vertex_shader_;
2128 Shader* fragment_shader_;
2129 Program* program_;
2130 ShaderManager shader_manager_;
2133 // GCC requires these declarations, but MSVC requires they not be present
2134 #ifndef COMPILER_MSVC
2135 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
2136 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
2137 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
2138 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
2139 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
2140 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
2141 #endif
2143 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
2144 SetShadersCompiled();
2145 SetExpectationsForProgramLink();
2146 SetExpectationsForProgramCached();
2147 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2148 base::Bind(&ShaderCacheCb)));
2151 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
2152 SetShadersCompiled();
2153 SetProgramCached();
2155 SetExpectationsForNoCompile(vertex_shader_);
2156 SetExpectationsForNoCompile(fragment_shader_);
2157 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
2158 SetExpectationsForNotCachingProgram();
2159 SetExpectationsForProgramLoadSuccess();
2161 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2162 base::Bind(&ShaderCacheCb)));
2165 } // namespace gles2
2166 } // namespace gpu