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"
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"
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
;
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
{
51 ProgramManagerTest() : manager_(NULL
, kMaxVaryingVectors
) { }
52 ~ProgramManagerTest() override
{ manager_
.Destroy(false); }
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
);
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
))
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
))
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
{
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
;
204 typedef TestHelper::AttribInfo AttribInfo
;
205 typedef TestHelper::UniformInfo UniformInfo
;
219 VarCategory category
;
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
,
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
,
252 TestHelper::SetupShader(
253 gl_
.get(), attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
256 void SetupDefaultShaderExpectations() {
257 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
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
,
275 program
->Link(NULL
, Program::kCountOnlyStaticallyUsed
,
276 base::Bind(&ShaderCacheCb
));
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
) {
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
) {
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
);
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
);
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
);
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
) {
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
);
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
);
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
);
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
);
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
);
382 const GLuint kClientProgramId
= 6666;
383 const GLuint kServiceProgramId
= 8888;
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
));
392 static AttribInfo kAttribs
[];
393 static UniformInfo kUniforms
[];
395 ProgramManager manager_
;
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
;
446 const size_t ProgramManagerWithShaderTest::kNumAttribs
=
447 arraysize(ProgramManagerWithShaderTest::kAttribs
);
449 ProgramManagerWithShaderTest::UniformInfo
450 ProgramManagerWithShaderTest::kUniforms
[] = {
454 kUniform1FakeLocation
,
455 kUniform1RealLocation
,
456 kUniform1DesiredLocation
,
462 kUniform2FakeLocation
,
463 kUniform2RealLocation
,
464 kUniform2DesiredLocation
,
465 kUniform2NameWithArrayIndex
,
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
=
487 const char* ProgramManagerWithShaderTest::kUniform3Name
= "uniform3";
488 const char* ProgramManagerWithShaderTest::kUniform3NameWithArrayIndex
=
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
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
);
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
[] = {
674 kUniform1FakeLocation
,
675 kUniform1RealLocation
,
676 kUniform1DesiredLocation
,
683 kUniform2FakeLocation
,
685 kUniform2DesiredLocation
,
686 kUniform2NameWithArrayIndex
,
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;
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);
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
));
723 program
->GetProgramiv(GL_ACTIVE_ATTRIBUTES
, &value
);
725 // Check that we didn't skip the "gl_" uniform.
726 program
->GetProgramiv(GL_ACTIVE_UNIFORMS
, &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
[] = {
747 kUniform1FakeLocation
,
748 kUniform1RealLocation
,
749 kUniform1DesiredLocation
,
755 kUniform2FakeLocation
,
756 kUniform2RealLocation
,
757 kUniform2DesiredLocation
,
763 kUniform3FakeLocation
,
764 kUniform3RealLocation
,
765 kUniform3DesiredLocation
,
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;
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);
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
[] = {
854 kUniform1FakeLocation
,
855 kUniform1RealLocation
,
856 kUniform1DesiredLocation
,
862 kUniform2FakeLocation
,
863 kUniform2RealLocation
,
864 kUniform2DesiredLocation
,
865 kUniform2NameWithArrayIndex
,
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
,
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.
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
;
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
);
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
;
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
))
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
))
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
*>(
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());
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
) {
1073 ProgramManager::MakeFakeLocation(expected
.fake_location
, 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());
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());
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
);
1124 UniformBlocksHeader header
;
1125 UniformBlockInfo entry
[2];
1127 uint32_t indices0
[2];
1129 uint32_t indices1
[1];
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
, _
, _
))
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()),
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
);
1291 TransformFeedbackVaryingsHeader header
;
1292 TransformFeedbackVaryingInfo entry
[2];
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()),
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
;
1337 EXPECT_CALL(*(gl_
.get()),
1338 GetTransformFeedbackVarying(
1339 kServiceProgramId
, ii
, max_length
, _
, _
, _
, _
))
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());
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
);
1392 UniformsES3Header header
;
1393 UniformES3Info entry
[2];
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
,
1422 GL_UNIFORM_ARRAY_STRIDE
,
1423 GL_UNIFORM_MATRIX_STRIDE
,
1424 GL_UNIFORM_IS_ROW_MAJOR
,
1426 const GLint
* kParams
[] = {
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
, _
,
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
*>(
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
);
1487 ProgramManager::MakeFakeLocation(expected
.fake_location
, 0),
1489 for (int32 jj
= 1; jj
< input
->size
; ++jj
)
1490 EXPECT_EQ(-1, locations
[jj
]);
1495 TEST_F(ProgramManagerWithShaderTest
, BindAttribLocationConflicts
) {
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(
1510 const char kAttribMatName
[] = "matAttrib";
1511 attrib_map
[kAttribMatName
] = TestHelper::ConstructAttribute(
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
);
1525 TestHelper::SetShaderStates(
1526 gl_
.get(), vshader
, true, NULL
, NULL
, NULL
, &attrib_map
, NULL
, 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
,
1545 const GLuint kClientProgramId
= 6666;
1546 const GLuint kServiceProgramId
= 8888;
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, _
))
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, _
))
1567 .RetiresOnSaturation();
1568 EXPECT_TRUE(LinkAsExpected(program
, true));
1570 program
->SetAttribLocationBinding(kAttrib2Name
, 1);
1571 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1572 EXPECT_CALL(*(gl_
.get()), BindAttribLocation(_
, _
, _
))
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(_
, _
, _
))
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
) {
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
);
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
);
1624 const GLuint kClientProgramId
= 6666;
1625 const GLuint kServiceProgramId
= 8888;
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
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
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);
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);
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
[] = {
1816 GL_SAMPLER_EXTERNAL_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
[] = {
1831 kUniform1FakeLocation
,
1832 kUniform1RealLocation
,
1833 kUniform1DesiredLocation
,
1839 kUniform2FakeLocation
,
1840 kUniform2RealLocation
,
1841 kUniform2DesiredLocation
,
1842 kUniform2NameWithArrayIndex
,
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
,
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
[] = {
1903 kUniform1FakeLocation
,
1904 kUniform1RealLocation
,
1905 kUniform1DesiredLocation
,
1911 kUniform2FakeLocation
,
1912 kUniform2RealLocation
,
1913 kUniform2DesiredLocation
,
1914 kUniform2NameWithArrayIndex
,
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
,
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
{
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
),
1957 ~ProgramManagerWithCacheTest() override
{
1958 manager_
.Destroy(false);
1959 shader_manager_
.Destroy(false);
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_
,
2003 void SetExpectationsForProgramCached(
2005 Shader
* vertex_shader
,
2006 Shader
* fragment_shader
) {
2007 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
2008 program
->service_id(),
2011 &program
->bind_attrib_location_map(),
2012 program_
->transform_feedback_varyings(),
2013 program_
->transform_feedback_buffer_mode(),
2017 void SetExpectationsForNotCachingProgram() {
2018 SetExpectationsForNotCachingProgram(program_
,
2023 void SetExpectationsForNotCachingProgram(
2025 Shader
* vertex_shader
,
2026 Shader
* fragment_shader
) {
2027 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
2028 program
->service_id(),
2031 &program
->bind_attrib_location_map(),
2032 program_
->transform_feedback_varyings(),
2033 program_
->transform_feedback_buffer_mode(),
2037 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result
) {
2038 SetExpectationsForProgramLoad(kServiceProgramId
,
2045 void SetExpectationsForProgramLoad(
2046 GLuint service_program_id
,
2048 Shader
* vertex_shader
,
2049 Shader
* fragment_shader
,
2050 ProgramCache::ProgramLoadResult result
) {
2051 EXPECT_CALL(*cache_
.get(),
2052 LoadLinkedProgram(service_program_id
,
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(),
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
,
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
, _
))
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, _
, _
))
2124 scoped_ptr
<MockProgramCache
> cache_
;
2125 ProgramManager manager_
;
2127 Shader
* vertex_shader_
;
2128 Shader
* fragment_shader_
;
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
;
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();
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