Don't add an aura tooltip to bubble close buttons on Windows.
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blob8e837023970eae59378be28b9af78bd714bfbe8c
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,
376 &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL);
377 TestHelper::SetShaderStates(
378 gl_.get(), fshader, true, 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 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
666 // that start with "gl_". Our implementation catches these and does not allow
667 // them back to client.
668 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
669 static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
670 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
671 { kUniform1Name,
672 kUniform1Size,
673 kUniform1Type,
674 kUniform1FakeLocation,
675 kUniform1RealLocation,
676 kUniform1DesiredLocation,
677 kUniform1Name,
679 { kUniform2Name,
680 kUniform2Size,
681 kUniform2Type,
682 kUniform2FakeLocation,
683 kUniform2RealLocation,
684 kUniform2DesiredLocation,
685 kUniform2NameWithArrayIndex,
687 { kUniform3Name,
688 kUniform3Size,
689 kUniform3Type,
690 kUniform3FakeLocation,
691 kUniform3RealLocation,
692 kUniform3DesiredLocation,
693 kUniform3NameWithArrayIndex,
696 const size_t kNumUniforms = arraysize(kUniforms);
697 static const GLuint kClientProgramId = 1234;
698 static const GLuint kServiceProgramId = 5679;
699 const GLuint kVShaderClientId = 2001;
700 const GLuint kFShaderClientId = 2002;
701 const GLuint kVShaderServiceId = 3001;
702 const GLuint kFShaderServiceId = 3002;
703 SetupShader(
704 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
705 Shader* vshader = shader_manager_.CreateShader(
706 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
707 ASSERT_TRUE(vshader != NULL);
708 TestHelper::SetShaderStates(gl_.get(), vshader, true);
709 Shader* fshader = shader_manager_.CreateShader(
710 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
711 ASSERT_TRUE(fshader != NULL);
712 TestHelper::SetShaderStates(gl_.get(), fshader, true);
713 Program* program =
714 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
715 ASSERT_TRUE(program != NULL);
716 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
717 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
718 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
719 base::Bind(&ShaderCacheCb));
720 GLint value = 0;
721 program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
722 EXPECT_EQ(3, value);
723 // Check that we skipped the "gl_" uniform.
724 program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
725 EXPECT_EQ(2, value);
726 // Check that our max length adds room for the array spec and is not as long
727 // as the "gl_" uniform we skipped.
728 // +4u is to account for "gl_" and NULL terminator.
729 program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
730 EXPECT_EQ(strlen(kUniform3Name) + 4u, static_cast<size_t>(value));
733 // Test the bug comparing similar array names is fixed.
734 TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
735 static const char* kUniform2Name = "u_nameLong[0]";
736 static const char* kUniform3Name = "u_name[0]";
737 static const GLint kUniform2Size = 2;
738 static const GLint kUniform3Size = 2;
739 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
740 { kUniform1Name,
741 kUniform1Size,
742 kUniform1Type,
743 kUniform1FakeLocation,
744 kUniform1RealLocation,
745 kUniform1DesiredLocation,
746 kUniform1Name,
748 { kUniform2Name,
749 kUniform2Size,
750 kUniform2Type,
751 kUniform2FakeLocation,
752 kUniform2RealLocation,
753 kUniform2DesiredLocation,
754 kUniform2Name,
756 { kUniform3Name,
757 kUniform3Size,
758 kUniform3Type,
759 kUniform3FakeLocation,
760 kUniform3RealLocation,
761 kUniform3DesiredLocation,
762 kUniform3Name,
765 const size_t kNumUniforms = arraysize(kUniforms);
766 static const GLuint kClientProgramId = 1234;
767 static const GLuint kServiceProgramId = 5679;
768 const GLuint kVShaderClientId = 2001;
769 const GLuint kFShaderClientId = 2002;
770 const GLuint kVShaderServiceId = 3001;
771 const GLuint kFShaderServiceId = 3002;
772 SetupShader(
773 kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
774 Shader* vshader = shader_manager_.CreateShader(
775 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
776 ASSERT_TRUE(vshader != NULL);
777 TestHelper::SetShaderStates(gl_.get(), vshader, true);
778 Shader* fshader = shader_manager_.CreateShader(
779 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
780 ASSERT_TRUE(fshader != NULL);
781 TestHelper::SetShaderStates(gl_.get(), fshader, true);
782 Program* program =
783 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
784 ASSERT_TRUE(program != NULL);
785 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
786 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
787 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
788 base::Bind(&ShaderCacheCb));
790 // Check that we get the correct locations.
791 EXPECT_EQ(kUniform2FakeLocation,
792 program->GetUniformFakeLocation(kUniform2Name));
793 EXPECT_EQ(kUniform3FakeLocation,
794 program->GetUniformFakeLocation(kUniform3Name));
797 // Some GL drivers incorrectly return the wrong type. For example they return
798 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
799 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
800 static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
801 static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
802 static GLenum kUniform2BadType = GL_FLOAT_VEC3;
803 static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
804 AttributeMap attrib_map;
805 UniformMap uniform_map;
806 VaryingMap varying_map;
807 attrib_map[kAttrib1Name] = TestHelper::ConstructAttribute(
808 kAttrib1Type, kAttrib1Size, kAttrib1Precision,
809 kAttribStaticUse, kAttrib1Name);
810 attrib_map[kAttrib2Name] = TestHelper::ConstructAttribute(
811 kAttrib2GoodType, kAttrib2Size, kAttrib2Precision,
812 kAttribStaticUse, kAttrib2Name);
813 attrib_map[kAttrib3Name] = TestHelper::ConstructAttribute(
814 kAttrib3Type, kAttrib3Size, kAttrib3Precision,
815 kAttribStaticUse, kAttrib3Name);
816 uniform_map[kUniform1Name] = TestHelper::ConstructUniform(
817 kUniform1Type, kUniform1Size, kUniform1Precision,
818 kUniform1StaticUse, kUniform1Name);
819 uniform_map[kUniform2Name] = TestHelper::ConstructUniform(
820 kUniform2GoodType, kUniform2Size, kUniform2Precision,
821 kUniform2StaticUse, kUniform2Name);
822 uniform_map[kUniform3Name] = TestHelper::ConstructUniform(
823 kUniform3Type, kUniform3Size, kUniform3Precision,
824 kUniform3StaticUse, kUniform3Name);
825 const GLuint kVShaderClientId = 2001;
826 const GLuint kFShaderClientId = 2002;
827 const GLuint kVShaderServiceId = 3001;
828 const GLuint kFShaderServiceId = 3002;
829 Shader* vshader = shader_manager_.CreateShader(
830 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
831 ASSERT_TRUE(vshader != NULL);
832 TestHelper::SetShaderStates(
833 gl_.get(), vshader, true, NULL, NULL,
834 &attrib_map, &uniform_map, &varying_map, NULL);
835 Shader* fshader = shader_manager_.CreateShader(
836 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
837 ASSERT_TRUE(fshader != NULL);
838 TestHelper::SetShaderStates(
839 gl_.get(), fshader, true, NULL, NULL,
840 &attrib_map, &uniform_map, &varying_map, NULL);
841 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
842 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
843 { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
844 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
846 static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
847 { kUniform1Name,
848 kUniform1Size,
849 kUniform1Type,
850 kUniform1FakeLocation,
851 kUniform1RealLocation,
852 kUniform1DesiredLocation,
853 kUniform1Name,
855 { kUniform2Name,
856 kUniform2Size,
857 kUniform2BadType,
858 kUniform2FakeLocation,
859 kUniform2RealLocation,
860 kUniform2DesiredLocation,
861 kUniform2NameWithArrayIndex,
863 { kUniform3Name,
864 kUniform3Size,
865 kUniform3Type,
866 kUniform3FakeLocation,
867 kUniform3RealLocation,
868 kUniform3DesiredLocation,
869 kUniform3NameWithArrayIndex,
872 const size_t kNumAttribs= arraysize(kAttribs);
873 const size_t kNumUniforms = arraysize(kUniforms);
874 static const GLuint kClientProgramId = 1234;
875 static const GLuint kServiceProgramId = 5679;
876 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
877 kServiceProgramId);
878 Program* program = manager_.CreateProgram(
879 kClientProgramId, kServiceProgramId);
880 ASSERT_TRUE(program!= NULL);
881 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
882 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
883 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
884 base::Bind(&ShaderCacheCb));
885 // Check that we got the good type, not the bad.
886 // Check Attribs
887 for (unsigned index = 0; index < kNumAttribs; ++index) {
888 const Program::VertexAttrib* attrib_info =
889 program->GetAttribInfo(index);
890 ASSERT_TRUE(attrib_info != NULL);
891 size_t pos = attrib_info->name.find_first_of("[.");
892 std::string top_name;
893 if (pos == std::string::npos)
894 top_name = attrib_info->name;
895 else
896 top_name = attrib_info->name.substr(0, pos);
897 AttributeMap::const_iterator it = attrib_map.find(top_name);
898 ASSERT_TRUE(it != attrib_map.end());
899 const sh::ShaderVariable* info;
900 std::string original_name;
901 EXPECT_TRUE(it->second.findInfoByMappedName(
902 attrib_info->name, &info, &original_name));
903 EXPECT_EQ(info->type, attrib_info->type);
904 EXPECT_EQ(static_cast<GLint>(info->arraySize), attrib_info->size);
905 EXPECT_EQ(original_name, attrib_info->name);
907 // Check Uniforms
908 for (unsigned index = 0; index < kNumUniforms; ++index) {
909 const Program::UniformInfo* uniform_info = program->GetUniformInfo(index);
910 ASSERT_TRUE(uniform_info != NULL);
911 size_t pos = uniform_info->name.find_first_of("[.");
912 std::string top_name;
913 if (pos == std::string::npos)
914 top_name = uniform_info->name;
915 else
916 top_name = uniform_info->name.substr(0, pos);
917 UniformMap::const_iterator it = uniform_map.find(top_name);
918 ASSERT_TRUE(it != uniform_map.end());
919 const sh::ShaderVariable* info;
920 std::string original_name;
921 EXPECT_TRUE(it->second.findInfoByMappedName(
922 uniform_info->name, &info, &original_name));
923 EXPECT_EQ(info->type, uniform_info->type);
924 EXPECT_EQ(static_cast<GLint>(info->arraySize), uniform_info->size);
925 EXPECT_EQ(original_name, uniform_info->name);
929 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
930 static const GLuint kClientProgramId = 124;
931 static const GLuint kServiceProgramId = 457;
932 Program* program = manager_.CreateProgram(
933 kClientProgramId, kServiceProgramId);
934 ASSERT_TRUE(program != NULL);
935 EXPECT_FALSE(program->CanLink());
936 const GLuint kVShaderClientId = 2001;
937 const GLuint kFShaderClientId = 2002;
938 const GLuint kVShaderServiceId = 3001;
939 const GLuint kFShaderServiceId = 3002;
940 Shader* vshader = shader_manager_.CreateShader(
941 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
942 ASSERT_TRUE(vshader != NULL);
943 TestHelper::SetShaderStates(gl_.get(), vshader, true);
944 Shader* fshader = shader_manager_.CreateShader(
945 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
946 ASSERT_TRUE(fshader != NULL);
947 TestHelper::SetShaderStates(gl_.get(), fshader, true);
948 EXPECT_FALSE(vshader->InUse());
949 EXPECT_FALSE(fshader->InUse());
950 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
951 EXPECT_TRUE(vshader->InUse());
952 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
953 EXPECT_TRUE(fshader->InUse());
954 EXPECT_TRUE(program->CanLink());
955 EXPECT_FALSE(program->InUse());
956 EXPECT_FALSE(program->IsDeleted());
957 manager_.UseProgram(program);
958 EXPECT_TRUE(program->InUse());
959 manager_.UseProgram(program);
960 EXPECT_TRUE(program->InUse());
961 manager_.MarkAsDeleted(&shader_manager_, program);
962 EXPECT_TRUE(program->IsDeleted());
963 Program* info2 = manager_.GetProgram(kClientProgramId);
964 EXPECT_EQ(program, info2);
965 manager_.UnuseProgram(&shader_manager_, program);
966 EXPECT_TRUE(program->InUse());
967 // this should delete the info.
968 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
969 .Times(1)
970 .RetiresOnSaturation();
971 manager_.UnuseProgram(&shader_manager_, program);
972 info2 = manager_.GetProgram(kClientProgramId);
973 EXPECT_TRUE(info2 == NULL);
974 EXPECT_FALSE(vshader->InUse());
975 EXPECT_FALSE(fshader->InUse());
978 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
979 static const GLuint kClientProgramId = 124;
980 static const GLuint kServiceProgramId = 457;
981 Program* program = manager_.CreateProgram(
982 kClientProgramId, kServiceProgramId);
983 ASSERT_TRUE(program != NULL);
984 EXPECT_FALSE(program->CanLink());
985 const GLuint kVShaderClientId = 2001;
986 const GLuint kFShaderClientId = 2002;
987 const GLuint kVShaderServiceId = 3001;
988 const GLuint kFShaderServiceId = 3002;
989 Shader* vshader = shader_manager_.CreateShader(
990 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
991 ASSERT_TRUE(vshader != NULL);
992 TestHelper::SetShaderStates(gl_.get(), vshader, true);
993 Shader* fshader = shader_manager_.CreateShader(
994 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
995 ASSERT_TRUE(fshader != NULL);
996 TestHelper::SetShaderStates(gl_.get(), fshader, true);
997 EXPECT_FALSE(vshader->InUse());
998 EXPECT_FALSE(fshader->InUse());
999 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1000 EXPECT_TRUE(vshader->InUse());
1001 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1002 EXPECT_TRUE(fshader->InUse());
1003 EXPECT_TRUE(program->CanLink());
1004 EXPECT_FALSE(program->InUse());
1005 EXPECT_FALSE(program->IsDeleted());
1006 manager_.UseProgram(program);
1007 EXPECT_TRUE(program->InUse());
1008 manager_.UseProgram(program);
1009 EXPECT_TRUE(program->InUse());
1010 manager_.UnuseProgram(&shader_manager_, program);
1011 EXPECT_TRUE(program->InUse());
1012 manager_.UnuseProgram(&shader_manager_, program);
1013 EXPECT_FALSE(program->InUse());
1014 Program* info2 = manager_.GetProgram(kClientProgramId);
1015 EXPECT_EQ(program, info2);
1016 // this should delete the program.
1017 EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
1018 .Times(1)
1019 .RetiresOnSaturation();
1020 manager_.MarkAsDeleted(&shader_manager_, program);
1021 info2 = manager_.GetProgram(kClientProgramId);
1022 EXPECT_TRUE(info2 == NULL);
1023 EXPECT_FALSE(vshader->InUse());
1024 EXPECT_FALSE(fshader->InUse());
1027 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
1028 CommonDecoder::Bucket bucket;
1029 const Program* program = manager_.GetProgram(kClientProgramId);
1030 ASSERT_TRUE(program != NULL);
1031 program->GetProgramInfo(&manager_, &bucket);
1032 ProgramInfoHeader* header =
1033 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1034 ASSERT_TRUE(header != NULL);
1035 EXPECT_EQ(1u, header->link_status);
1036 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1037 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1038 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1039 sizeof(*header),
1040 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1041 ASSERT_TRUE(inputs != NULL);
1042 const ProgramInput* input = inputs;
1043 // TODO(gman): Don't assume these are in order.
1044 for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
1045 const AttribInfo& expected = kAttribs[ii];
1046 EXPECT_EQ(expected.size, input->size);
1047 EXPECT_EQ(expected.type, input->type);
1048 const int32* location = bucket.GetDataAs<const int32*>(
1049 input->location_offset, sizeof(int32));
1050 ASSERT_TRUE(location != NULL);
1051 EXPECT_EQ(expected.location, *location);
1052 const char* name_buf = bucket.GetDataAs<const char*>(
1053 input->name_offset, input->name_length);
1054 ASSERT_TRUE(name_buf != NULL);
1055 std::string name(name_buf, input->name_length);
1056 EXPECT_STREQ(expected.name, name.c_str());
1057 ++input;
1059 // TODO(gman): Don't assume these are in order.
1060 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1061 const UniformInfo& expected = kUniforms[ii];
1062 EXPECT_EQ(expected.size, input->size);
1063 EXPECT_EQ(expected.type, input->type);
1064 const int32* locations = bucket.GetDataAs<const int32*>(
1065 input->location_offset, sizeof(int32) * input->size);
1066 ASSERT_TRUE(locations != NULL);
1067 for (int32 jj = 0; jj < input->size; ++jj) {
1068 EXPECT_EQ(
1069 ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1070 locations[jj]);
1072 const char* name_buf = bucket.GetDataAs<const char*>(
1073 input->name_offset, input->name_length);
1074 ASSERT_TRUE(name_buf != NULL);
1075 std::string name(name_buf, input->name_length);
1076 EXPECT_STREQ(expected.good_name, name.c_str());
1077 ++input;
1079 EXPECT_EQ(header->num_attribs + header->num_uniforms,
1080 static_cast<uint32>(input - inputs));
1083 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksNone) {
1084 CommonDecoder::Bucket bucket;
1085 const Program* program = manager_.GetProgram(kClientProgramId);
1086 ASSERT_TRUE(program != NULL);
1087 // The program's previous link failed.
1088 EXPECT_CALL(*(gl_.get()),
1089 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1090 .WillOnce(SetArgPointee<2>(GL_FALSE))
1091 .RetiresOnSaturation();
1092 EXPECT_TRUE(program->GetUniformBlocks(&bucket));
1093 EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size());
1094 UniformBlocksHeader* header =
1095 bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader));
1096 EXPECT_TRUE(header != NULL);
1097 EXPECT_EQ(0u, header->num_uniform_blocks);
1098 // Zero uniform blocks.
1099 EXPECT_CALL(*(gl_.get()),
1100 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1101 .WillOnce(SetArgPointee<2>(GL_TRUE))
1102 .RetiresOnSaturation();
1103 EXPECT_CALL(*(gl_.get()),
1104 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _))
1105 .WillOnce(SetArgPointee<2>(0))
1106 .RetiresOnSaturation();
1107 EXPECT_TRUE(program->GetUniformBlocks(&bucket));
1108 EXPECT_EQ(sizeof(UniformBlocksHeader), bucket.size());
1109 header =
1110 bucket.GetDataAs<UniformBlocksHeader*>(0, sizeof(UniformBlocksHeader));
1111 EXPECT_TRUE(header != NULL);
1112 EXPECT_EQ(0u, header->num_uniform_blocks);
1115 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformBlocksValid) {
1116 CommonDecoder::Bucket bucket;
1117 const Program* program = manager_.GetProgram(kClientProgramId);
1118 ASSERT_TRUE(program != NULL);
1119 struct Data {
1120 UniformBlocksHeader header;
1121 UniformBlockInfo entry[2];
1122 char name0[4];
1123 uint32_t indices0[2];
1124 char name1[8];
1125 uint32_t indices1[1];
1127 Data data;
1128 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1129 // This is a testing only problem.
1130 const char* kName[] = { "cow", "chicken" };
1131 const uint32_t kIndices0[] = { 1, 2 };
1132 const uint32_t kIndices1[] = { 3 };
1133 const uint32_t* kIndices[] = { kIndices0, kIndices1 };
1134 data.header.num_uniform_blocks = 2;
1135 data.entry[0].binding = 0;
1136 data.entry[0].data_size = 8;
1137 data.entry[0].name_offset = ComputeOffset(&data, data.name0);
1138 data.entry[0].name_length = arraysize(data.name0);
1139 data.entry[0].active_uniforms = arraysize(data.indices0);
1140 data.entry[0].active_uniform_offset = ComputeOffset(&data, data.indices0);
1141 data.entry[0].referenced_by_vertex_shader = static_cast<uint32_t>(true);
1142 data.entry[0].referenced_by_fragment_shader = static_cast<uint32_t>(false);
1143 data.entry[1].binding = 1;
1144 data.entry[1].data_size = 4;
1145 data.entry[1].name_offset = ComputeOffset(&data, data.name1);
1146 data.entry[1].name_length = arraysize(data.name1);
1147 data.entry[1].active_uniforms = arraysize(data.indices1);
1148 data.entry[1].active_uniform_offset = ComputeOffset(&data, data.indices1);
1149 data.entry[1].referenced_by_vertex_shader = static_cast<uint32_t>(false);
1150 data.entry[1].referenced_by_fragment_shader = static_cast<uint32_t>(true);
1151 memcpy(data.name0, kName[0], arraysize(data.name0));
1152 data.indices0[0] = kIndices[0][0];
1153 data.indices0[1] = kIndices[0][1];
1154 memcpy(data.name1, kName[1], arraysize(data.name1));
1155 data.indices1[0] = kIndices[1][0];
1157 EXPECT_CALL(*(gl_.get()),
1158 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1159 .WillOnce(SetArgPointee<2>(GL_TRUE))
1160 .RetiresOnSaturation();
1161 EXPECT_CALL(*(gl_.get()),
1162 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORM_BLOCKS, _))
1163 .WillOnce(SetArgPointee<2>(data.header.num_uniform_blocks))
1164 .RetiresOnSaturation();
1165 EXPECT_CALL(*(gl_.get()),
1166 GetProgramiv(kServiceProgramId,
1167 GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, _))
1168 .WillOnce(SetArgPointee<2>(
1169 1 + std::max(strlen(kName[0]), strlen(kName[1]))))
1170 .RetiresOnSaturation();
1171 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) {
1172 EXPECT_CALL(*(gl_.get()),
1173 GetActiveUniformBlockiv(
1174 kServiceProgramId, ii, GL_UNIFORM_BLOCK_BINDING, _))
1175 .WillOnce(SetArgPointee<3>(data.entry[ii].binding))
1176 .RetiresOnSaturation();
1177 EXPECT_CALL(*(gl_.get()),
1178 GetActiveUniformBlockiv(
1179 kServiceProgramId, ii, GL_UNIFORM_BLOCK_DATA_SIZE, _))
1180 .WillOnce(SetArgPointee<3>(data.entry[ii].data_size))
1181 .RetiresOnSaturation();
1182 EXPECT_CALL(*(gl_.get()),
1183 GetActiveUniformBlockiv(
1184 kServiceProgramId, ii, GL_UNIFORM_BLOCK_NAME_LENGTH, _))
1185 .WillOnce(SetArgPointee<3>(data.entry[ii].name_length))
1186 .RetiresOnSaturation();
1187 EXPECT_CALL(*(gl_.get()),
1188 GetActiveUniformBlockName(
1189 kServiceProgramId, ii, data.entry[ii].name_length, _, _))
1190 .WillOnce(DoAll(
1191 SetArgPointee<3>(strlen(kName[ii])),
1192 SetArrayArgument<4>(
1193 kName[ii], kName[ii] + data.entry[ii].name_length)))
1194 .RetiresOnSaturation();
1195 EXPECT_CALL(*(gl_.get()),
1196 GetActiveUniformBlockiv(
1197 kServiceProgramId, ii, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, _))
1198 .WillOnce(SetArgPointee<3>(data.entry[ii].active_uniforms))
1199 .RetiresOnSaturation();
1200 EXPECT_CALL(*(gl_.get()),
1201 GetActiveUniformBlockiv(
1202 kServiceProgramId, ii,
1203 GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, _))
1204 .WillOnce(SetArgPointee<3>(data.entry[ii].referenced_by_vertex_shader))
1205 .RetiresOnSaturation();
1206 EXPECT_CALL(*(gl_.get()),
1207 GetActiveUniformBlockiv(
1208 kServiceProgramId, ii,
1209 GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, _))
1210 .WillOnce(SetArgPointee<3>(
1211 data.entry[ii].referenced_by_fragment_shader))
1212 .RetiresOnSaturation();
1214 for (uint32_t ii = 0; ii < data.header.num_uniform_blocks; ++ii) {
1215 EXPECT_CALL(*(gl_.get()),
1216 GetActiveUniformBlockiv(
1217 kServiceProgramId, ii,
1218 GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, _))
1219 .WillOnce(SetArrayArgument<3>(
1220 kIndices[ii], kIndices[ii] + data.entry[ii].active_uniforms))
1221 .RetiresOnSaturation();
1223 program->GetUniformBlocks(&bucket);
1224 EXPECT_EQ(sizeof(Data), bucket.size());
1225 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1226 EXPECT_TRUE(bucket_data != NULL);
1227 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1230 TEST_F(ProgramManagerWithShaderTest,
1231 ProgramInfoGetTransformFeedbackVaryingsNone) {
1232 CommonDecoder::Bucket bucket;
1233 const Program* program = manager_.GetProgram(kClientProgramId);
1234 ASSERT_TRUE(program != NULL);
1235 // The program's previous link failed.
1236 EXPECT_CALL(*(gl_.get()),
1237 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1238 .WillOnce(SetArgPointee<2>(GL_FALSE))
1239 .RetiresOnSaturation();
1240 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1241 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1242 TransformFeedbackVaryingsHeader* header =
1243 bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1244 0, sizeof(TransformFeedbackVaryingsHeader));
1245 EXPECT_TRUE(header != NULL);
1246 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1247 // Zero uniform blocks.
1248 EXPECT_CALL(*(gl_.get()),
1249 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1250 .WillOnce(SetArgPointee<2>(GL_TRUE))
1251 .RetiresOnSaturation();
1252 EXPECT_CALL(*(gl_.get()),
1253 GetProgramiv(
1254 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1255 .WillOnce(SetArgPointee<2>(0))
1256 .RetiresOnSaturation();
1257 EXPECT_TRUE(program->GetTransformFeedbackVaryings(&bucket));
1258 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader), bucket.size());
1259 header = bucket.GetDataAs<TransformFeedbackVaryingsHeader*>(
1260 0, sizeof(TransformFeedbackVaryingsHeader));
1261 EXPECT_TRUE(header != NULL);
1262 EXPECT_EQ(0u, header->num_transform_feedback_varyings);
1265 TEST_F(ProgramManagerWithShaderTest,
1266 ProgramInfoGetTransformFeedbackVaryingsValid) {
1267 CommonDecoder::Bucket bucket;
1268 const Program* program = manager_.GetProgram(kClientProgramId);
1269 ASSERT_TRUE(program != NULL);
1270 struct Data {
1271 TransformFeedbackVaryingsHeader header;
1272 TransformFeedbackVaryingInfo entry[2];
1273 char name0[4];
1274 char name1[8];
1276 Data data;
1277 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1278 // This is a testing only problem.
1279 const char* kName[] = { "cow", "chicken" };
1280 data.header.num_transform_feedback_varyings = 2;
1281 data.entry[0].size = 1;
1282 data.entry[0].type = GL_FLOAT_VEC2;
1283 data.entry[0].name_offset = ComputeOffset(&data, data.name0);
1284 data.entry[0].name_length = arraysize(data.name0);
1285 data.entry[1].size = 2;
1286 data.entry[1].type = GL_FLOAT;
1287 data.entry[1].name_offset = ComputeOffset(&data, data.name1);
1288 data.entry[1].name_length = arraysize(data.name1);
1289 memcpy(data.name0, kName[0], arraysize(data.name0));
1290 memcpy(data.name1, kName[1], arraysize(data.name1));
1292 EXPECT_CALL(*(gl_.get()),
1293 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1294 .WillOnce(SetArgPointee<2>(GL_TRUE))
1295 .RetiresOnSaturation();
1296 EXPECT_CALL(*(gl_.get()),
1297 GetProgramiv(
1298 kServiceProgramId, GL_TRANSFORM_FEEDBACK_VARYINGS, _))
1299 .WillOnce(SetArgPointee<2>(data.header.num_transform_feedback_varyings))
1300 .RetiresOnSaturation();
1301 GLsizei max_length = 1 + std::max(strlen(kName[0]), strlen(kName[1]));
1302 EXPECT_CALL(*(gl_.get()),
1303 GetProgramiv(kServiceProgramId,
1304 GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, _))
1305 .WillOnce(SetArgPointee<2>(max_length))
1306 .RetiresOnSaturation();
1307 for (uint32_t ii = 0; ii < data.header.num_transform_feedback_varyings;
1308 ++ii) {
1309 EXPECT_CALL(*(gl_.get()),
1310 GetTransformFeedbackVarying(
1311 kServiceProgramId, ii, max_length, _, _, _, _))
1312 .WillOnce(DoAll(
1313 SetArgPointee<3>(data.entry[ii].name_length - 1),
1314 SetArgPointee<4>(data.entry[ii].size),
1315 SetArgPointee<5>(data.entry[ii].type),
1316 SetArrayArgument<6>(
1317 kName[ii], kName[ii] + data.entry[ii].name_length)))
1318 .RetiresOnSaturation();
1320 program->GetTransformFeedbackVaryings(&bucket);
1321 EXPECT_EQ(sizeof(Data), bucket.size());
1322 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1323 EXPECT_TRUE(bucket_data != NULL);
1324 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1327 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3None) {
1328 CommonDecoder::Bucket bucket;
1329 const Program* program = manager_.GetProgram(kClientProgramId);
1330 ASSERT_TRUE(program != NULL);
1331 // The program's previous link failed.
1332 EXPECT_CALL(*(gl_.get()),
1333 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1334 .WillOnce(SetArgPointee<2>(GL_FALSE))
1335 .RetiresOnSaturation();
1336 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1337 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1338 UniformsES3Header* header =
1339 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1340 EXPECT_TRUE(header != NULL);
1341 EXPECT_EQ(0u, header->num_uniforms);
1342 // Zero uniform blocks.
1343 EXPECT_CALL(*(gl_.get()),
1344 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1345 .WillOnce(SetArgPointee<2>(GL_TRUE))
1346 .RetiresOnSaturation();
1347 EXPECT_CALL(*(gl_.get()),
1348 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1349 .WillOnce(SetArgPointee<2>(0))
1350 .RetiresOnSaturation();
1351 EXPECT_TRUE(program->GetUniformsES3(&bucket));
1352 EXPECT_EQ(sizeof(UniformsES3Header), bucket.size());
1353 header =
1354 bucket.GetDataAs<UniformsES3Header*>(0, sizeof(UniformsES3Header));
1355 EXPECT_TRUE(header != NULL);
1356 EXPECT_EQ(0u, header->num_uniforms);
1359 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetUniformsES3Valid) {
1360 CommonDecoder::Bucket bucket;
1361 const Program* program = manager_.GetProgram(kClientProgramId);
1362 ASSERT_TRUE(program != NULL);
1363 struct Data {
1364 UniformsES3Header header;
1365 UniformES3Info entry[2];
1367 Data data;
1368 const GLint kBlockIndex[] = { -1, 2 };
1369 const GLint kOffset[] = { 3, 4 };
1370 const GLint kArrayStride[] = { 7, 8 };
1371 const GLint kMatrixStride[] = { 9, 10 };
1372 const GLint kIsRowMajor[] = { 0, 1 };
1373 data.header.num_uniforms = 2;
1374 for (uint32_t ii = 0; ii < data.header.num_uniforms; ++ii) {
1375 data.entry[ii].block_index = kBlockIndex[ii];
1376 data.entry[ii].offset = kOffset[ii];
1377 data.entry[ii].array_stride = kArrayStride[ii];
1378 data.entry[ii].matrix_stride = kMatrixStride[ii];
1379 data.entry[ii].is_row_major = kIsRowMajor[ii];
1382 EXPECT_CALL(*(gl_.get()),
1383 GetProgramiv(kServiceProgramId, GL_LINK_STATUS, _))
1384 .WillOnce(SetArgPointee<2>(GL_TRUE))
1385 .RetiresOnSaturation();
1386 EXPECT_CALL(*(gl_.get()),
1387 GetProgramiv(kServiceProgramId, GL_ACTIVE_UNIFORMS, _))
1388 .WillOnce(SetArgPointee<2>(data.header.num_uniforms))
1389 .RetiresOnSaturation();
1391 const GLenum kPname[] = {
1392 GL_UNIFORM_BLOCK_INDEX,
1393 GL_UNIFORM_OFFSET,
1394 GL_UNIFORM_ARRAY_STRIDE,
1395 GL_UNIFORM_MATRIX_STRIDE,
1396 GL_UNIFORM_IS_ROW_MAJOR,
1398 const GLint* kParams[] = {
1399 kBlockIndex,
1400 kOffset,
1401 kArrayStride,
1402 kMatrixStride,
1403 kIsRowMajor,
1405 const size_t kNumIterations = arraysize(kPname);
1406 for (size_t ii = 0; ii < kNumIterations; ++ii) {
1407 EXPECT_CALL(*(gl_.get()),
1408 GetActiveUniformsiv(
1409 kServiceProgramId, data.header.num_uniforms, _,
1410 kPname[ii], _))
1411 .WillOnce(SetArrayArgument<4>(
1412 kParams[ii], kParams[ii] + data.header.num_uniforms))
1413 .RetiresOnSaturation();
1416 program->GetUniformsES3(&bucket);
1417 EXPECT_EQ(sizeof(Data), bucket.size());
1418 Data* bucket_data = bucket.GetDataAs<Data*>(0, sizeof(Data));
1419 EXPECT_TRUE(bucket_data != NULL);
1420 EXPECT_EQ(0, memcmp(&data, bucket_data, sizeof(Data)));
1423 // Some drivers optimize out unused uniform array elements, so their
1424 // location would be -1.
1425 TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
1426 CommonDecoder::Bucket bucket;
1427 const Program* program = manager_.GetProgram(kClientProgramId);
1428 ASSERT_TRUE(program != NULL);
1429 // Emulate the situation that only the first element has a valid location.
1430 // TODO(zmo): Don't assume these are in order.
1431 for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
1432 Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
1433 program->GetUniformInfo(ii));
1434 ASSERT_TRUE(uniform != NULL);
1435 EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
1436 uniform->element_locations.size());
1437 for (GLsizei jj = 1; jj < uniform->size; ++jj)
1438 uniform->element_locations[jj] = -1;
1440 program->GetProgramInfo(&manager_, &bucket);
1441 ProgramInfoHeader* header =
1442 bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1443 ASSERT_TRUE(header != NULL);
1444 EXPECT_EQ(1u, header->link_status);
1445 EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1446 EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1447 const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1448 sizeof(*header),
1449 sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1450 ASSERT_TRUE(inputs != NULL);
1451 const ProgramInput* input = inputs + header->num_attribs;
1452 for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1453 const UniformInfo& expected = kUniforms[ii];
1454 EXPECT_EQ(expected.size, input->size);
1455 const int32* locations = bucket.GetDataAs<const int32*>(
1456 input->location_offset, sizeof(int32) * input->size);
1457 ASSERT_TRUE(locations != NULL);
1458 EXPECT_EQ(
1459 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1460 locations[0]);
1461 for (int32 jj = 1; jj < input->size; ++jj)
1462 EXPECT_EQ(-1, locations[jj]);
1463 ++input;
1467 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1468 // Set up shader
1469 const GLuint kVShaderClientId = 1;
1470 const GLuint kVShaderServiceId = 11;
1471 const GLuint kFShaderClientId = 2;
1472 const GLuint kFShaderServiceId = 12;
1473 AttributeMap attrib_map;
1474 for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
1475 attrib_map[kAttribs[ii].name] = TestHelper::ConstructAttribute(
1476 kAttribs[ii].type,
1477 kAttribs[ii].size,
1478 GL_MEDIUM_FLOAT,
1479 kAttribStaticUse,
1480 kAttribs[ii].name);
1482 const char kAttribMatName[] = "matAttrib";
1483 attrib_map[kAttribMatName] = TestHelper::ConstructAttribute(
1484 GL_FLOAT_MAT2,
1486 GL_MEDIUM_FLOAT,
1487 kAttribStaticUse,
1488 kAttribMatName);
1489 // Check we can create shader.
1490 Shader* vshader = shader_manager_.CreateShader(
1491 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1492 Shader* fshader = shader_manager_.CreateShader(
1493 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1494 // Check shader got created.
1495 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1496 // Set Status
1497 TestHelper::SetShaderStates(
1498 gl_.get(), vshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1499 // Check attrib infos got copied.
1500 for (AttributeMap::const_iterator it = attrib_map.begin();
1501 it != attrib_map.end(); ++it) {
1502 const sh::Attribute* variable_info =
1503 vshader->GetAttribInfo(it->first);
1504 ASSERT_TRUE(variable_info != NULL);
1505 EXPECT_EQ(it->second.type, variable_info->type);
1506 EXPECT_EQ(it->second.arraySize, variable_info->arraySize);
1507 EXPECT_EQ(it->second.precision, variable_info->precision);
1508 EXPECT_EQ(it->second.staticUse, variable_info->staticUse);
1509 EXPECT_EQ(it->second.name, variable_info->name);
1511 TestHelper::SetShaderStates(
1512 gl_.get(), fshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1514 // Set up program
1515 const GLuint kClientProgramId = 6666;
1516 const GLuint kServiceProgramId = 8888;
1517 Program* program =
1518 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1519 ASSERT_TRUE(program != NULL);
1520 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1521 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1523 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1524 EXPECT_TRUE(LinkAsExpected(program, true));
1526 program->SetAttribLocationBinding(kAttrib1Name, 0);
1527 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1528 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1529 .Times(1)
1530 .RetiresOnSaturation();
1531 EXPECT_TRUE(LinkAsExpected(program, true));
1533 program->SetAttribLocationBinding("xxx", 0);
1534 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1535 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, 0, _))
1536 .Times(1)
1537 .RetiresOnSaturation();
1538 EXPECT_TRUE(LinkAsExpected(program, true));
1540 program->SetAttribLocationBinding(kAttrib2Name, 1);
1541 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1542 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1543 .Times(2)
1544 .RetiresOnSaturation();
1545 EXPECT_TRUE(LinkAsExpected(program, true));
1547 program->SetAttribLocationBinding(kAttrib2Name, 0);
1548 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1549 EXPECT_TRUE(LinkAsExpected(program, false));
1551 program->SetAttribLocationBinding(kAttribMatName, 1);
1552 program->SetAttribLocationBinding(kAttrib2Name, 3);
1553 EXPECT_CALL(*(gl_.get()), BindAttribLocation(_, _, _))
1554 .Times(3)
1555 .RetiresOnSaturation();
1556 EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1557 EXPECT_TRUE(LinkAsExpected(program, true));
1559 program->SetAttribLocationBinding(kAttrib2Name, 2);
1560 EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1561 EXPECT_TRUE(LinkAsExpected(program, false));
1564 TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
1565 // Set up shader
1566 const GLuint kVShaderClientId = 1;
1567 const GLuint kVShaderServiceId = 11;
1568 const GLuint kFShaderClientId = 2;
1569 const GLuint kFShaderServiceId = 12;
1571 UniformMap vertex_uniform_map;
1572 vertex_uniform_map["a"] = TestHelper::ConstructUniform(
1573 GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a");
1574 UniformMap frag_uniform_map;
1575 frag_uniform_map["a"] = TestHelper::ConstructUniform(
1576 GL_FLOAT, 3, GL_LOW_FLOAT, true, "a");
1578 // Check we can create shader.
1579 Shader* vshader = shader_manager_.CreateShader(
1580 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1581 Shader* fshader = shader_manager_.CreateShader(
1582 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1583 // Check shader got created.
1584 ASSERT_TRUE(vshader != NULL && fshader != NULL);
1585 // Set Status
1586 TestHelper::SetShaderStates(
1587 gl_.get(), vshader, true, NULL, NULL, NULL,
1588 &vertex_uniform_map, NULL, NULL);
1589 TestHelper::SetShaderStates(
1590 gl_.get(), fshader, true, NULL, NULL, NULL,
1591 &frag_uniform_map, NULL, NULL);
1593 // Set up program
1594 const GLuint kClientProgramId = 6666;
1595 const GLuint kServiceProgramId = 8888;
1596 Program* program =
1597 manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1598 ASSERT_TRUE(program != NULL);
1599 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1600 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1602 std::string conflicting_name;
1604 EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1605 EXPECT_EQ("a", conflicting_name);
1606 EXPECT_TRUE(LinkAsExpected(program, false));
1609 // If a varying has different type in the vertex and fragment
1610 // shader, linking should fail.
1611 TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
1612 const VarInfo kVertexVarying =
1613 { GL_FLOAT_VEC3, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1614 const VarInfo kFragmentVarying =
1615 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1616 Program* program = SetupShaderVariableTest(
1617 &kVertexVarying, 1, &kFragmentVarying, 1);
1619 std::string conflicting_name;
1621 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1622 EXPECT_EQ("a", conflicting_name);
1623 EXPECT_TRUE(LinkAsExpected(program, false));
1626 // If a varying has different array size in the vertex and fragment
1627 // shader, linking should fail.
1628 TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
1629 const VarInfo kVertexVarying =
1630 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1631 const VarInfo kFragmentVarying =
1632 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1633 Program* program = SetupShaderVariableTest(
1634 &kVertexVarying, 1, &kFragmentVarying, 1);
1636 std::string conflicting_name;
1638 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1639 EXPECT_EQ("a", conflicting_name);
1640 EXPECT_TRUE(LinkAsExpected(program, false));
1643 // If a varying has different precision in the vertex and fragment
1644 // shader, linking should succeed.
1645 TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
1646 const VarInfo kVertexVarying =
1647 { GL_FLOAT, 2, GL_HIGH_FLOAT, true, "a", kVarVarying };
1648 const VarInfo kFragmentVarying =
1649 { GL_FLOAT, 2, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1650 Program* program = SetupShaderVariableTest(
1651 &kVertexVarying, 1, &kFragmentVarying, 1);
1653 std::string conflicting_name;
1655 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1656 EXPECT_TRUE(conflicting_name.empty());
1657 EXPECT_TRUE(LinkAsExpected(program, true));
1660 // If a varying is statically used in fragment shader but not
1661 // declared in vertex shader, link should fail.
1662 TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
1663 const VarInfo kFragmentVarying =
1664 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, true, "a", kVarVarying };
1665 Program* program = SetupShaderVariableTest(
1666 NULL, 0, &kFragmentVarying, 1);
1668 std::string conflicting_name;
1670 EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1671 EXPECT_EQ("a", conflicting_name);
1672 EXPECT_TRUE(LinkAsExpected(program, false));
1675 // If a varying is declared but not statically used in fragment
1676 // shader, even if it's not declared in vertex shader, link should
1677 // succeed.
1678 TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
1679 const VarInfo kFragmentVarying =
1680 { GL_FLOAT, 3, GL_MEDIUM_FLOAT, false, "a", kVarVarying };
1681 Program* program = SetupShaderVariableTest(
1682 NULL, 0, &kFragmentVarying, 1);
1684 std::string conflicting_name;
1686 EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1687 EXPECT_TRUE(conflicting_name.empty());
1688 EXPECT_TRUE(LinkAsExpected(program, true));
1691 // Uniforms and attributes are both global variables, thus sharing
1692 // the same namespace. Any name conflicts should cause link
1693 // failure.
1694 TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
1695 const VarInfo kVertexAttribute =
1696 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarAttribute };
1697 const VarInfo kFragmentUniform =
1698 { GL_FLOAT_VEC4, 1, GL_MEDIUM_FLOAT, true, "a", kVarUniform };
1699 Program* program = SetupShaderVariableTest(
1700 &kVertexAttribute, 1, &kFragmentUniform, 1);
1702 std::string conflicting_name;
1704 EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1705 EXPECT_EQ("a", conflicting_name);
1706 EXPECT_TRUE(LinkAsExpected(program, false));
1709 // Varyings go over 8 rows.
1710 TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
1711 const VarInfo kVertexVaryings[] = {
1712 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1713 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1715 const VarInfo kFragmentVaryings[] = {
1716 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1717 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1719 Program* program = SetupShaderVariableTest(
1720 kVertexVaryings, 2, kFragmentVaryings, 2);
1722 EXPECT_FALSE(
1723 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1724 EXPECT_TRUE(LinkAsExpected(program, false));
1727 // Varyings go over 8 rows but some are inactive
1728 TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
1729 const VarInfo kVertexVaryings[] = {
1730 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1731 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1733 const VarInfo kFragmentVaryings[] = {
1734 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1735 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1737 Program* program = SetupShaderVariableTest(
1738 kVertexVaryings, 2, kFragmentVaryings, 2);
1740 EXPECT_TRUE(
1741 program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1742 EXPECT_TRUE(LinkAsExpected(program, true));
1745 // Varyings go over 8 rows but some are inactive.
1746 // However, we still fail the check if kCountAll option is used.
1747 TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
1748 const VarInfo kVertexVaryings[] = {
1749 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, true, "a", kVarVarying },
1750 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1752 const VarInfo kFragmentVaryings[] = {
1753 { GL_FLOAT_VEC4, 4, GL_MEDIUM_FLOAT, false, "a", kVarVarying },
1754 { GL_FLOAT_VEC4, 5, GL_MEDIUM_FLOAT, true, "b", kVarVarying }
1756 Program* program = SetupShaderVariableTest(
1757 kVertexVaryings, 2, kFragmentVaryings, 2);
1759 EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1762 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
1763 const GLuint kVShaderClientId = 2001;
1764 const GLuint kFShaderClientId = 2002;
1765 const GLuint kVShaderServiceId = 3001;
1766 const GLuint kFShaderServiceId = 3002;
1767 Shader* vshader = shader_manager_.CreateShader(
1768 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1769 ASSERT_TRUE(vshader != NULL);
1770 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1771 Shader* fshader = shader_manager_.CreateShader(
1772 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1773 ASSERT_TRUE(fshader != NULL);
1774 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1775 static const GLuint kClientProgramId = 1234;
1776 static const GLuint kServiceProgramId = 5679;
1777 Program* program = manager_.CreateProgram(
1778 kClientProgramId, kServiceProgramId);
1779 ASSERT_TRUE(program != NULL);
1780 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1781 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1783 static const GLenum kSamplerTypes[] = {
1784 GL_SAMPLER_2D,
1785 GL_SAMPLER_CUBE,
1786 GL_SAMPLER_EXTERNAL_OES,
1787 GL_SAMPLER_3D_OES,
1788 GL_SAMPLER_2D_RECT_ARB,
1790 const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
1791 for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
1792 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1793 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1794 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1795 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1797 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1798 { kUniform1Name,
1799 kUniform1Size,
1800 kUniform1Type,
1801 kUniform1FakeLocation,
1802 kUniform1RealLocation,
1803 kUniform1DesiredLocation,
1804 kUniform1Name,
1806 { kUniform2Name,
1807 kUniform2Size,
1808 kSamplerTypes[ii],
1809 kUniform2FakeLocation,
1810 kUniform2RealLocation,
1811 kUniform2DesiredLocation,
1812 kUniform2NameWithArrayIndex,
1814 { kUniform3Name,
1815 kUniform3Size,
1816 kUniform3Type,
1817 kUniform3FakeLocation,
1818 kUniform3RealLocation,
1819 kUniform3DesiredLocation,
1820 kUniform3NameWithArrayIndex,
1823 const size_t kNumAttribs = arraysize(kAttribs);
1824 const size_t kNumUniforms = arraysize(kUniforms);
1825 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1826 kServiceProgramId);
1827 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1828 base::Bind(&ShaderCacheCb));
1829 SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
1830 manager_.ClearUniforms(program);
1834 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
1835 const GLuint kVShaderClientId = 2001;
1836 const GLuint kFShaderClientId = 2002;
1837 const GLuint kVShaderServiceId = 3001;
1838 const GLuint kFShaderServiceId = 3002;
1840 const GLint kUniform1DesiredLocation = 10;
1841 const GLint kUniform2DesiredLocation = -1;
1842 const GLint kUniform3DesiredLocation = 5;
1844 Shader* vshader = shader_manager_.CreateShader(
1845 kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1846 ASSERT_TRUE(vshader != NULL);
1847 TestHelper::SetShaderStates(gl_.get(), vshader, true);
1848 Shader* fshader = shader_manager_.CreateShader(
1849 kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1850 ASSERT_TRUE(fshader != NULL);
1851 TestHelper::SetShaderStates(gl_.get(), fshader, true);
1852 static const GLuint kClientProgramId = 1234;
1853 static const GLuint kServiceProgramId = 5679;
1854 Program* program = manager_.CreateProgram(
1855 kClientProgramId, kServiceProgramId);
1856 ASSERT_TRUE(program != NULL);
1857 EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1858 EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1859 EXPECT_TRUE(program->SetUniformLocationBinding(
1860 kUniform1Name, kUniform1DesiredLocation));
1861 EXPECT_TRUE(program->SetUniformLocationBinding(
1862 kUniform3Name, kUniform3DesiredLocation));
1864 static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1865 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1866 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1867 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1869 ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1870 { kUniform1Name,
1871 kUniform1Size,
1872 kUniform1Type,
1873 kUniform1FakeLocation,
1874 kUniform1RealLocation,
1875 kUniform1DesiredLocation,
1876 kUniform1Name,
1878 { kUniform2Name,
1879 kUniform2Size,
1880 kUniform2Type,
1881 kUniform2FakeLocation,
1882 kUniform2RealLocation,
1883 kUniform2DesiredLocation,
1884 kUniform2NameWithArrayIndex,
1886 { kUniform3Name,
1887 kUniform3Size,
1888 kUniform3Type,
1889 kUniform3FakeLocation,
1890 kUniform3RealLocation,
1891 kUniform3DesiredLocation,
1892 kUniform3NameWithArrayIndex,
1896 const size_t kNumAttribs = arraysize(kAttribs);
1897 const size_t kNumUniforms = arraysize(kUniforms);
1898 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1899 kServiceProgramId);
1900 program->Link(NULL, Program::kCountOnlyStaticallyUsed,
1901 base::Bind(&ShaderCacheCb));
1903 EXPECT_EQ(kUniform1DesiredLocation,
1904 program->GetUniformFakeLocation(kUniform1Name));
1905 EXPECT_EQ(kUniform3DesiredLocation,
1906 program->GetUniformFakeLocation(kUniform3Name));
1907 EXPECT_EQ(kUniform3DesiredLocation,
1908 program->GetUniformFakeLocation(kUniform3NameWithArrayIndex));
1911 class ProgramManagerWithCacheTest : public GpuServiceTest {
1912 public:
1913 static const GLuint kClientProgramId = 1;
1914 static const GLuint kServiceProgramId = 10;
1915 static const GLuint kVertexShaderClientId = 2;
1916 static const GLuint kFragmentShaderClientId = 20;
1917 static const GLuint kVertexShaderServiceId = 3;
1918 static const GLuint kFragmentShaderServiceId = 30;
1920 ProgramManagerWithCacheTest()
1921 : cache_(new MockProgramCache()),
1922 manager_(cache_.get(), kMaxVaryingVectors),
1923 vertex_shader_(NULL),
1924 fragment_shader_(NULL),
1925 program_(NULL) {
1927 ~ProgramManagerWithCacheTest() override {
1928 manager_.Destroy(false);
1929 shader_manager_.Destroy(false);
1932 protected:
1933 void SetUp() override {
1934 GpuServiceTest::SetUp();
1936 vertex_shader_ = shader_manager_.CreateShader(
1937 kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
1938 fragment_shader_ = shader_manager_.CreateShader(
1939 kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
1940 ASSERT_TRUE(vertex_shader_ != NULL);
1941 ASSERT_TRUE(fragment_shader_ != NULL);
1942 vertex_shader_->set_source("lka asjf bjajsdfj");
1943 fragment_shader_->set_source("lka asjf a fasgag 3rdsf3 bjajsdfj");
1945 program_ = manager_.CreateProgram(
1946 kClientProgramId, kServiceProgramId);
1947 ASSERT_TRUE(program_ != NULL);
1949 program_->AttachShader(&shader_manager_, vertex_shader_);
1950 program_->AttachShader(&shader_manager_, fragment_shader_);
1953 void SetShadersCompiled() {
1954 TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
1955 TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
1958 void SetProgramCached() {
1959 cache_->LinkedProgramCacheSuccess(
1960 vertex_shader_->source(),
1961 fragment_shader_->source(),
1962 &program_->bind_attrib_location_map(),
1963 program_->transform_feedback_varyings(),
1964 program_->transform_feedback_buffer_mode());
1967 void SetExpectationsForProgramCached() {
1968 SetExpectationsForProgramCached(program_,
1969 vertex_shader_,
1970 fragment_shader_);
1973 void SetExpectationsForProgramCached(
1974 Program* program,
1975 Shader* vertex_shader,
1976 Shader* fragment_shader) {
1977 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1978 program->service_id(),
1979 vertex_shader,
1980 fragment_shader,
1981 &program->bind_attrib_location_map(),
1982 program_->transform_feedback_varyings(),
1983 program_->transform_feedback_buffer_mode(),
1984 _)).Times(1);
1987 void SetExpectationsForNotCachingProgram() {
1988 SetExpectationsForNotCachingProgram(program_,
1989 vertex_shader_,
1990 fragment_shader_);
1993 void SetExpectationsForNotCachingProgram(
1994 Program* program,
1995 Shader* vertex_shader,
1996 Shader* fragment_shader) {
1997 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1998 program->service_id(),
1999 vertex_shader,
2000 fragment_shader,
2001 &program->bind_attrib_location_map(),
2002 program_->transform_feedback_varyings(),
2003 program_->transform_feedback_buffer_mode(),
2004 _)).Times(0);
2007 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
2008 SetExpectationsForProgramLoad(kServiceProgramId,
2009 program_,
2010 vertex_shader_,
2011 fragment_shader_,
2012 result);
2015 void SetExpectationsForProgramLoad(
2016 GLuint service_program_id,
2017 Program* program,
2018 Shader* vertex_shader,
2019 Shader* fragment_shader,
2020 ProgramCache::ProgramLoadResult result) {
2021 EXPECT_CALL(*cache_.get(),
2022 LoadLinkedProgram(service_program_id,
2023 vertex_shader,
2024 fragment_shader,
2025 &program->bind_attrib_location_map(),
2026 program_->transform_feedback_varyings(),
2027 program_->transform_feedback_buffer_mode(),
2029 .WillOnce(Return(result));
2032 void SetExpectationsForProgramLoadSuccess() {
2033 SetExpectationsForProgramLoadSuccess(kServiceProgramId);
2036 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
2037 TestHelper::SetupProgramSuccessExpectations(gl_.get(),
2038 NULL,
2040 NULL,
2042 service_program_id);
2045 void SetExpectationsForProgramLink() {
2046 SetExpectationsForProgramLink(kServiceProgramId);
2049 void SetExpectationsForProgramLink(GLuint service_program_id) {
2050 TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
2051 if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
2052 EXPECT_CALL(*gl_.get(),
2053 ProgramParameteri(service_program_id,
2054 PROGRAM_BINARY_RETRIEVABLE_HINT,
2055 GL_TRUE)).Times(1);
2059 void SetExpectationsForSuccessCompile(
2060 const Shader* shader) {
2061 const GLuint shader_id = shader->service_id();
2062 const char* src = shader->source().c_str();
2063 EXPECT_CALL(*gl_.get(),
2064 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2065 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2066 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2067 .WillOnce(SetArgPointee<2>(GL_TRUE));
2070 void SetExpectationsForNoCompile(const Shader* shader) {
2071 const GLuint shader_id = shader->service_id();
2072 const char* src = shader->source().c_str();
2073 EXPECT_CALL(*gl_.get(),
2074 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
2075 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
2076 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2077 .Times(0);
2080 void SetExpectationsForErrorCompile(const Shader* shader) {
2081 const GLuint shader_id = shader->service_id();
2082 const char* src = shader->source().c_str();
2083 EXPECT_CALL(*gl_.get(),
2084 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
2085 EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
2086 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
2087 .WillOnce(SetArgPointee<2>(GL_FALSE));
2088 EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
2089 .WillOnce(SetArgPointee<2>(0));
2090 EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
2091 .Times(1);
2094 scoped_ptr<MockProgramCache> cache_;
2095 ProgramManager manager_;
2097 Shader* vertex_shader_;
2098 Shader* fragment_shader_;
2099 Program* program_;
2100 ShaderManager shader_manager_;
2103 // GCC requires these declarations, but MSVC requires they not be present
2104 #ifndef COMPILER_MSVC
2105 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
2106 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
2107 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
2108 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
2109 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
2110 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
2111 #endif
2113 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
2114 SetShadersCompiled();
2115 SetExpectationsForProgramLink();
2116 SetExpectationsForProgramCached();
2117 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2118 base::Bind(&ShaderCacheCb)));
2121 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
2122 SetShadersCompiled();
2123 SetProgramCached();
2125 SetExpectationsForNoCompile(vertex_shader_);
2126 SetExpectationsForNoCompile(fragment_shader_);
2127 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
2128 SetExpectationsForNotCachingProgram();
2129 SetExpectationsForProgramLoadSuccess();
2131 EXPECT_TRUE(program_->Link(NULL, Program::kCountOnlyStaticallyUsed,
2132 base::Bind(&ShaderCacheCb)));
2135 } // namespace gles2
2136 } // namespace gpu