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
, GL_LINK_STATUS
, _
))
1242 .WillOnce(SetArgPointee
<2>(GL_FALSE
))
1243 .RetiresOnSaturation();
1244 EXPECT_TRUE(program
->GetTransformFeedbackVaryings(&bucket
));
1245 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader
), bucket
.size());
1246 TransformFeedbackVaryingsHeader
* header
=
1247 bucket
.GetDataAs
<TransformFeedbackVaryingsHeader
*>(
1248 0, sizeof(TransformFeedbackVaryingsHeader
));
1249 EXPECT_TRUE(header
!= NULL
);
1250 EXPECT_EQ(0u, header
->num_transform_feedback_varyings
);
1251 // Zero uniform blocks.
1252 EXPECT_CALL(*(gl_
.get()),
1253 GetProgramiv(kServiceProgramId
, GL_LINK_STATUS
, _
))
1254 .WillOnce(SetArgPointee
<2>(GL_TRUE
))
1255 .RetiresOnSaturation();
1256 EXPECT_CALL(*(gl_
.get()),
1258 kServiceProgramId
, GL_TRANSFORM_FEEDBACK_VARYINGS
, _
))
1259 .WillOnce(SetArgPointee
<2>(0))
1260 .RetiresOnSaturation();
1261 EXPECT_TRUE(program
->GetTransformFeedbackVaryings(&bucket
));
1262 EXPECT_EQ(sizeof(TransformFeedbackVaryingsHeader
), bucket
.size());
1263 header
= bucket
.GetDataAs
<TransformFeedbackVaryingsHeader
*>(
1264 0, sizeof(TransformFeedbackVaryingsHeader
));
1265 EXPECT_TRUE(header
!= NULL
);
1266 EXPECT_EQ(0u, header
->num_transform_feedback_varyings
);
1269 TEST_F(ProgramManagerWithShaderTest
,
1270 ProgramInfoGetTransformFeedbackVaryingsValid
) {
1271 CommonDecoder::Bucket bucket
;
1272 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1273 ASSERT_TRUE(program
!= NULL
);
1275 TransformFeedbackVaryingsHeader header
;
1276 TransformFeedbackVaryingInfo entry
[2];
1281 // The names needs to be of size 4*k-1 to avoid padding in the struct Data.
1282 // This is a testing only problem.
1283 const char* kName
[] = { "cow", "chicken" };
1284 data
.header
.num_transform_feedback_varyings
= 2;
1285 data
.entry
[0].size
= 1;
1286 data
.entry
[0].type
= GL_FLOAT_VEC2
;
1287 data
.entry
[0].name_offset
= ComputeOffset(&data
, data
.name0
);
1288 data
.entry
[0].name_length
= arraysize(data
.name0
);
1289 data
.entry
[1].size
= 2;
1290 data
.entry
[1].type
= GL_FLOAT
;
1291 data
.entry
[1].name_offset
= ComputeOffset(&data
, data
.name1
);
1292 data
.entry
[1].name_length
= arraysize(data
.name1
);
1293 memcpy(data
.name0
, kName
[0], arraysize(data
.name0
));
1294 memcpy(data
.name1
, kName
[1], arraysize(data
.name1
));
1296 EXPECT_CALL(*(gl_
.get()),
1297 GetProgramiv(kServiceProgramId
, GL_LINK_STATUS
, _
))
1298 .WillOnce(SetArgPointee
<2>(GL_TRUE
))
1299 .RetiresOnSaturation();
1300 EXPECT_CALL(*(gl_
.get()),
1302 kServiceProgramId
, GL_TRANSFORM_FEEDBACK_VARYINGS
, _
))
1303 .WillOnce(SetArgPointee
<2>(data
.header
.num_transform_feedback_varyings
))
1304 .RetiresOnSaturation();
1305 GLsizei max_length
= 1 + std::max(strlen(kName
[0]), strlen(kName
[1]));
1306 EXPECT_CALL(*(gl_
.get()),
1307 GetProgramiv(kServiceProgramId
,
1308 GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
, _
))
1309 .WillOnce(SetArgPointee
<2>(max_length
))
1310 .RetiresOnSaturation();
1311 for (uint32_t ii
= 0; ii
< data
.header
.num_transform_feedback_varyings
;
1313 EXPECT_CALL(*(gl_
.get()),
1314 GetTransformFeedbackVarying(
1315 kServiceProgramId
, ii
, max_length
, _
, _
, _
, _
))
1317 SetArgPointee
<3>(data
.entry
[ii
].name_length
- 1),
1318 SetArgPointee
<4>(data
.entry
[ii
].size
),
1319 SetArgPointee
<5>(data
.entry
[ii
].type
),
1320 SetArrayArgument
<6>(
1321 kName
[ii
], kName
[ii
] + data
.entry
[ii
].name_length
)))
1322 .RetiresOnSaturation();
1324 program
->GetTransformFeedbackVaryings(&bucket
);
1325 EXPECT_EQ(sizeof(Data
), bucket
.size());
1326 Data
* bucket_data
= bucket
.GetDataAs
<Data
*>(0, sizeof(Data
));
1327 EXPECT_TRUE(bucket_data
!= NULL
);
1328 EXPECT_EQ(0, memcmp(&data
, bucket_data
, sizeof(Data
)));
1331 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoGetUniformsES3None
) {
1332 CommonDecoder::Bucket bucket
;
1333 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1334 ASSERT_TRUE(program
!= NULL
);
1335 // The program's previous link failed.
1336 EXPECT_CALL(*(gl_
.get()),
1337 GetProgramiv(kServiceProgramId
, GL_LINK_STATUS
, _
))
1338 .WillOnce(SetArgPointee
<2>(GL_FALSE
))
1339 .RetiresOnSaturation();
1340 EXPECT_TRUE(program
->GetUniformsES3(&bucket
));
1341 EXPECT_EQ(sizeof(UniformsES3Header
), bucket
.size());
1342 UniformsES3Header
* header
=
1343 bucket
.GetDataAs
<UniformsES3Header
*>(0, sizeof(UniformsES3Header
));
1344 EXPECT_TRUE(header
!= NULL
);
1345 EXPECT_EQ(0u, header
->num_uniforms
);
1346 // Zero uniform blocks.
1347 EXPECT_CALL(*(gl_
.get()),
1348 GetProgramiv(kServiceProgramId
, GL_LINK_STATUS
, _
))
1349 .WillOnce(SetArgPointee
<2>(GL_TRUE
))
1350 .RetiresOnSaturation();
1351 EXPECT_CALL(*(gl_
.get()),
1352 GetProgramiv(kServiceProgramId
, GL_ACTIVE_UNIFORMS
, _
))
1353 .WillOnce(SetArgPointee
<2>(0))
1354 .RetiresOnSaturation();
1355 EXPECT_TRUE(program
->GetUniformsES3(&bucket
));
1356 EXPECT_EQ(sizeof(UniformsES3Header
), bucket
.size());
1358 bucket
.GetDataAs
<UniformsES3Header
*>(0, sizeof(UniformsES3Header
));
1359 EXPECT_TRUE(header
!= NULL
);
1360 EXPECT_EQ(0u, header
->num_uniforms
);
1363 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoGetUniformsES3Valid
) {
1364 CommonDecoder::Bucket bucket
;
1365 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1366 ASSERT_TRUE(program
!= NULL
);
1368 UniformsES3Header header
;
1369 UniformES3Info entry
[2];
1372 const GLint kBlockIndex
[] = { -1, 2 };
1373 const GLint kOffset
[] = { 3, 4 };
1374 const GLint kArrayStride
[] = { 7, 8 };
1375 const GLint kMatrixStride
[] = { 9, 10 };
1376 const GLint kIsRowMajor
[] = { 0, 1 };
1377 data
.header
.num_uniforms
= 2;
1378 for (uint32_t ii
= 0; ii
< data
.header
.num_uniforms
; ++ii
) {
1379 data
.entry
[ii
].block_index
= kBlockIndex
[ii
];
1380 data
.entry
[ii
].offset
= kOffset
[ii
];
1381 data
.entry
[ii
].array_stride
= kArrayStride
[ii
];
1382 data
.entry
[ii
].matrix_stride
= kMatrixStride
[ii
];
1383 data
.entry
[ii
].is_row_major
= kIsRowMajor
[ii
];
1386 EXPECT_CALL(*(gl_
.get()),
1387 GetProgramiv(kServiceProgramId
, GL_LINK_STATUS
, _
))
1388 .WillOnce(SetArgPointee
<2>(GL_TRUE
))
1389 .RetiresOnSaturation();
1390 EXPECT_CALL(*(gl_
.get()),
1391 GetProgramiv(kServiceProgramId
, GL_ACTIVE_UNIFORMS
, _
))
1392 .WillOnce(SetArgPointee
<2>(data
.header
.num_uniforms
))
1393 .RetiresOnSaturation();
1395 const GLenum kPname
[] = {
1396 GL_UNIFORM_BLOCK_INDEX
,
1398 GL_UNIFORM_ARRAY_STRIDE
,
1399 GL_UNIFORM_MATRIX_STRIDE
,
1400 GL_UNIFORM_IS_ROW_MAJOR
,
1402 const GLint
* kParams
[] = {
1409 const size_t kNumIterations
= arraysize(kPname
);
1410 for (size_t ii
= 0; ii
< kNumIterations
; ++ii
) {
1411 EXPECT_CALL(*(gl_
.get()),
1412 GetActiveUniformsiv(
1413 kServiceProgramId
, data
.header
.num_uniforms
, _
,
1415 .WillOnce(SetArrayArgument
<4>(
1416 kParams
[ii
], kParams
[ii
] + data
.header
.num_uniforms
))
1417 .RetiresOnSaturation();
1420 program
->GetUniformsES3(&bucket
);
1421 EXPECT_EQ(sizeof(Data
), bucket
.size());
1422 Data
* bucket_data
= bucket
.GetDataAs
<Data
*>(0, sizeof(Data
));
1423 EXPECT_TRUE(bucket_data
!= NULL
);
1424 EXPECT_EQ(0, memcmp(&data
, bucket_data
, sizeof(Data
)));
1427 // Some drivers optimize out unused uniform array elements, so their
1428 // location would be -1.
1429 TEST_F(ProgramManagerWithShaderTest
, UnusedUniformArrayElements
) {
1430 CommonDecoder::Bucket bucket
;
1431 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1432 ASSERT_TRUE(program
!= NULL
);
1433 // Emulate the situation that only the first element has a valid location.
1434 // TODO(zmo): Don't assume these are in order.
1435 for (size_t ii
= 0; ii
< arraysize(kUniforms
); ++ii
) {
1436 Program::UniformInfo
* uniform
= const_cast<Program::UniformInfo
*>(
1437 program
->GetUniformInfo(ii
));
1438 ASSERT_TRUE(uniform
!= NULL
);
1439 EXPECT_EQ(static_cast<size_t>(kUniforms
[ii
].size
),
1440 uniform
->element_locations
.size());
1441 for (GLsizei jj
= 1; jj
< uniform
->size
; ++jj
)
1442 uniform
->element_locations
[jj
] = -1;
1444 program
->GetProgramInfo(&manager_
, &bucket
);
1445 ProgramInfoHeader
* header
=
1446 bucket
.GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
1447 ASSERT_TRUE(header
!= NULL
);
1448 EXPECT_EQ(1u, header
->link_status
);
1449 EXPECT_EQ(arraysize(kAttribs
), header
->num_attribs
);
1450 EXPECT_EQ(arraysize(kUniforms
), header
->num_uniforms
);
1451 const ProgramInput
* inputs
= bucket
.GetDataAs
<const ProgramInput
*>(
1453 sizeof(ProgramInput
) * (header
->num_attribs
+ header
->num_uniforms
));
1454 ASSERT_TRUE(inputs
!= NULL
);
1455 const ProgramInput
* input
= inputs
+ header
->num_attribs
;
1456 for (uint32 ii
= 0; ii
< header
->num_uniforms
; ++ii
) {
1457 const UniformInfo
& expected
= kUniforms
[ii
];
1458 EXPECT_EQ(expected
.size
, input
->size
);
1459 const int32
* locations
= bucket
.GetDataAs
<const int32
*>(
1460 input
->location_offset
, sizeof(int32
) * input
->size
);
1461 ASSERT_TRUE(locations
!= NULL
);
1463 ProgramManager::MakeFakeLocation(expected
.fake_location
, 0),
1465 for (int32 jj
= 1; jj
< input
->size
; ++jj
)
1466 EXPECT_EQ(-1, locations
[jj
]);
1471 TEST_F(ProgramManagerWithShaderTest
, BindAttribLocationConflicts
) {
1473 const GLuint kVShaderClientId
= 1;
1474 const GLuint kVShaderServiceId
= 11;
1475 const GLuint kFShaderClientId
= 2;
1476 const GLuint kFShaderServiceId
= 12;
1477 AttributeMap attrib_map
;
1478 for (uint32 ii
= 0; ii
< kNumAttribs
; ++ii
) {
1479 attrib_map
[kAttribs
[ii
].name
] = TestHelper::ConstructAttribute(
1486 const char kAttribMatName
[] = "matAttrib";
1487 attrib_map
[kAttribMatName
] = TestHelper::ConstructAttribute(
1493 // Check we can create shader.
1494 Shader
* vshader
= shader_manager_
.CreateShader(
1495 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1496 Shader
* fshader
= shader_manager_
.CreateShader(
1497 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1498 // Check shader got created.
1499 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1501 TestHelper::SetShaderStates(
1502 gl_
.get(), vshader
, true, NULL
, NULL
, NULL
, &attrib_map
, NULL
, NULL
,
1504 // Check attrib infos got copied.
1505 for (AttributeMap::const_iterator it
= attrib_map
.begin();
1506 it
!= attrib_map
.end(); ++it
) {
1507 const sh::Attribute
* variable_info
=
1508 vshader
->GetAttribInfo(it
->first
);
1509 ASSERT_TRUE(variable_info
!= NULL
);
1510 EXPECT_EQ(it
->second
.type
, variable_info
->type
);
1511 EXPECT_EQ(it
->second
.arraySize
, variable_info
->arraySize
);
1512 EXPECT_EQ(it
->second
.precision
, variable_info
->precision
);
1513 EXPECT_EQ(it
->second
.staticUse
, variable_info
->staticUse
);
1514 EXPECT_EQ(it
->second
.name
, variable_info
->name
);
1516 TestHelper::SetShaderStates(
1517 gl_
.get(), fshader
, true, NULL
, NULL
, NULL
, &attrib_map
, NULL
, NULL
,
1521 const GLuint kClientProgramId
= 6666;
1522 const GLuint kServiceProgramId
= 8888;
1524 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1525 ASSERT_TRUE(program
!= NULL
);
1526 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1527 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1529 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1530 EXPECT_TRUE(LinkAsExpected(program
, true));
1532 program
->SetAttribLocationBinding(kAttrib1Name
, 0);
1533 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1534 EXPECT_CALL(*(gl_
.get()), BindAttribLocation(_
, 0, _
))
1536 .RetiresOnSaturation();
1537 EXPECT_TRUE(LinkAsExpected(program
, true));
1539 program
->SetAttribLocationBinding("xxx", 0);
1540 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1541 EXPECT_CALL(*(gl_
.get()), BindAttribLocation(_
, 0, _
))
1543 .RetiresOnSaturation();
1544 EXPECT_TRUE(LinkAsExpected(program
, true));
1546 program
->SetAttribLocationBinding(kAttrib2Name
, 1);
1547 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1548 EXPECT_CALL(*(gl_
.get()), BindAttribLocation(_
, _
, _
))
1550 .RetiresOnSaturation();
1551 EXPECT_TRUE(LinkAsExpected(program
, true));
1553 program
->SetAttribLocationBinding(kAttrib2Name
, 0);
1554 EXPECT_TRUE(program
->DetectAttribLocationBindingConflicts());
1555 EXPECT_TRUE(LinkAsExpected(program
, false));
1557 program
->SetAttribLocationBinding(kAttribMatName
, 1);
1558 program
->SetAttribLocationBinding(kAttrib2Name
, 3);
1559 EXPECT_CALL(*(gl_
.get()), BindAttribLocation(_
, _
, _
))
1561 .RetiresOnSaturation();
1562 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1563 EXPECT_TRUE(LinkAsExpected(program
, true));
1565 program
->SetAttribLocationBinding(kAttrib2Name
, 2);
1566 EXPECT_TRUE(program
->DetectAttribLocationBindingConflicts());
1567 EXPECT_TRUE(LinkAsExpected(program
, false));
1570 TEST_F(ProgramManagerWithShaderTest
, UniformsPrecisionMismatch
) {
1572 const GLuint kVShaderClientId
= 1;
1573 const GLuint kVShaderServiceId
= 11;
1574 const GLuint kFShaderClientId
= 2;
1575 const GLuint kFShaderServiceId
= 12;
1577 UniformMap vertex_uniform_map
;
1578 vertex_uniform_map
["a"] = TestHelper::ConstructUniform(
1579 GL_FLOAT
, 3, GL_MEDIUM_FLOAT
, true, "a");
1580 UniformMap frag_uniform_map
;
1581 frag_uniform_map
["a"] = TestHelper::ConstructUniform(
1582 GL_FLOAT
, 3, GL_LOW_FLOAT
, true, "a");
1584 // Check we can create shader.
1585 Shader
* vshader
= shader_manager_
.CreateShader(
1586 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1587 Shader
* fshader
= shader_manager_
.CreateShader(
1588 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1589 // Check shader got created.
1590 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1592 TestHelper::SetShaderStates(
1593 gl_
.get(), vshader
, true, NULL
, NULL
, NULL
, NULL
,
1594 &vertex_uniform_map
, NULL
, NULL
);
1595 TestHelper::SetShaderStates(
1596 gl_
.get(), fshader
, true, NULL
, NULL
, NULL
, NULL
,
1597 &frag_uniform_map
, NULL
, NULL
);
1600 const GLuint kClientProgramId
= 6666;
1601 const GLuint kServiceProgramId
= 8888;
1603 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1604 ASSERT_TRUE(program
!= NULL
);
1605 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1606 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1608 std::string conflicting_name
;
1610 EXPECT_TRUE(program
->DetectUniformsMismatch(&conflicting_name
));
1611 EXPECT_EQ("a", conflicting_name
);
1612 EXPECT_TRUE(LinkAsExpected(program
, false));
1615 // If a varying has different type in the vertex and fragment
1616 // shader, linking should fail.
1617 TEST_F(ProgramManagerWithShaderTest
, VaryingTypeMismatch
) {
1618 const VarInfo kVertexVarying
=
1619 { GL_FLOAT_VEC3
, 1, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1620 const VarInfo kFragmentVarying
=
1621 { GL_FLOAT_VEC4
, 1, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1622 Program
* program
= SetupShaderVariableTest(
1623 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1625 std::string conflicting_name
;
1627 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1628 EXPECT_EQ("a", conflicting_name
);
1629 EXPECT_TRUE(LinkAsExpected(program
, false));
1632 // If a varying has different array size in the vertex and fragment
1633 // shader, linking should fail.
1634 TEST_F(ProgramManagerWithShaderTest
, VaryingArraySizeMismatch
) {
1635 const VarInfo kVertexVarying
=
1636 { GL_FLOAT
, 2, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1637 const VarInfo kFragmentVarying
=
1638 { GL_FLOAT
, 3, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1639 Program
* program
= SetupShaderVariableTest(
1640 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1642 std::string conflicting_name
;
1644 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1645 EXPECT_EQ("a", conflicting_name
);
1646 EXPECT_TRUE(LinkAsExpected(program
, false));
1649 // If a varying has different precision in the vertex and fragment
1650 // shader, linking should succeed.
1651 TEST_F(ProgramManagerWithShaderTest
, VaryingPrecisionMismatch
) {
1652 const VarInfo kVertexVarying
=
1653 { GL_FLOAT
, 2, GL_HIGH_FLOAT
, true, "a", kVarVarying
};
1654 const VarInfo kFragmentVarying
=
1655 { GL_FLOAT
, 2, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1656 Program
* program
= SetupShaderVariableTest(
1657 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1659 std::string conflicting_name
;
1661 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1662 EXPECT_TRUE(conflicting_name
.empty());
1663 EXPECT_TRUE(LinkAsExpected(program
, true));
1666 // If a varying is statically used in fragment shader but not
1667 // declared in vertex shader, link should fail.
1668 TEST_F(ProgramManagerWithShaderTest
, VaryingMissing
) {
1669 const VarInfo kFragmentVarying
=
1670 { GL_FLOAT
, 3, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
};
1671 Program
* program
= SetupShaderVariableTest(
1672 NULL
, 0, &kFragmentVarying
, 1);
1674 std::string conflicting_name
;
1676 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1677 EXPECT_EQ("a", conflicting_name
);
1678 EXPECT_TRUE(LinkAsExpected(program
, false));
1681 // If a varying is declared but not statically used in fragment
1682 // shader, even if it's not declared in vertex shader, link should
1684 TEST_F(ProgramManagerWithShaderTest
, InactiveVarying
) {
1685 const VarInfo kFragmentVarying
=
1686 { GL_FLOAT
, 3, GL_MEDIUM_FLOAT
, false, "a", kVarVarying
};
1687 Program
* program
= SetupShaderVariableTest(
1688 NULL
, 0, &kFragmentVarying
, 1);
1690 std::string conflicting_name
;
1692 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1693 EXPECT_TRUE(conflicting_name
.empty());
1694 EXPECT_TRUE(LinkAsExpected(program
, true));
1697 // Uniforms and attributes are both global variables, thus sharing
1698 // the same namespace. Any name conflicts should cause link
1700 TEST_F(ProgramManagerWithShaderTest
, AttribUniformNameConflict
) {
1701 const VarInfo kVertexAttribute
=
1702 { GL_FLOAT_VEC4
, 1, GL_MEDIUM_FLOAT
, true, "a", kVarAttribute
};
1703 const VarInfo kFragmentUniform
=
1704 { GL_FLOAT_VEC4
, 1, GL_MEDIUM_FLOAT
, true, "a", kVarUniform
};
1705 Program
* program
= SetupShaderVariableTest(
1706 &kVertexAttribute
, 1, &kFragmentUniform
, 1);
1708 std::string conflicting_name
;
1710 EXPECT_TRUE(program
->DetectGlobalNameConflicts(&conflicting_name
));
1711 EXPECT_EQ("a", conflicting_name
);
1712 EXPECT_TRUE(LinkAsExpected(program
, false));
1715 // Varyings go over 8 rows.
1716 TEST_F(ProgramManagerWithShaderTest
, TooManyVaryings
) {
1717 const VarInfo kVertexVaryings
[] = {
1718 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
},
1719 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1721 const VarInfo kFragmentVaryings
[] = {
1722 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
},
1723 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1725 Program
* program
= SetupShaderVariableTest(
1726 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1729 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1730 EXPECT_TRUE(LinkAsExpected(program
, false));
1733 // Varyings go over 8 rows but some are inactive
1734 TEST_F(ProgramManagerWithShaderTest
, TooManyInactiveVaryings
) {
1735 const VarInfo kVertexVaryings
[] = {
1736 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
},
1737 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1739 const VarInfo kFragmentVaryings
[] = {
1740 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, false, "a", kVarVarying
},
1741 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1743 Program
* program
= SetupShaderVariableTest(
1744 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1747 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1748 EXPECT_TRUE(LinkAsExpected(program
, true));
1751 // Varyings go over 8 rows but some are inactive.
1752 // However, we still fail the check if kCountAll option is used.
1753 TEST_F(ProgramManagerWithShaderTest
, CountAllVaryingsInPacking
) {
1754 const VarInfo kVertexVaryings
[] = {
1755 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, true, "a", kVarVarying
},
1756 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1758 const VarInfo kFragmentVaryings
[] = {
1759 { GL_FLOAT_VEC4
, 4, GL_MEDIUM_FLOAT
, false, "a", kVarVarying
},
1760 { GL_FLOAT_VEC4
, 5, GL_MEDIUM_FLOAT
, true, "b", kVarVarying
}
1762 Program
* program
= SetupShaderVariableTest(
1763 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1765 EXPECT_FALSE(program
->CheckVaryingsPacking(Program::kCountAll
));
1768 TEST_F(ProgramManagerWithShaderTest
, ClearWithSamplerTypes
) {
1769 const GLuint kVShaderClientId
= 2001;
1770 const GLuint kFShaderClientId
= 2002;
1771 const GLuint kVShaderServiceId
= 3001;
1772 const GLuint kFShaderServiceId
= 3002;
1773 Shader
* vshader
= shader_manager_
.CreateShader(
1774 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1775 ASSERT_TRUE(vshader
!= NULL
);
1776 TestHelper::SetShaderStates(gl_
.get(), vshader
, true);
1777 Shader
* fshader
= shader_manager_
.CreateShader(
1778 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1779 ASSERT_TRUE(fshader
!= NULL
);
1780 TestHelper::SetShaderStates(gl_
.get(), fshader
, true);
1781 static const GLuint kClientProgramId
= 1234;
1782 static const GLuint kServiceProgramId
= 5679;
1783 Program
* program
= manager_
.CreateProgram(
1784 kClientProgramId
, kServiceProgramId
);
1785 ASSERT_TRUE(program
!= NULL
);
1786 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1787 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1789 static const GLenum kSamplerTypes
[] = {
1792 GL_SAMPLER_EXTERNAL_OES
,
1794 GL_SAMPLER_2D_RECT_ARB
,
1796 const size_t kNumSamplerTypes
= arraysize(kSamplerTypes
);
1797 for (size_t ii
= 0; ii
< kNumSamplerTypes
; ++ii
) {
1798 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1799 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1800 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1801 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1803 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1807 kUniform1FakeLocation
,
1808 kUniform1RealLocation
,
1809 kUniform1DesiredLocation
,
1815 kUniform2FakeLocation
,
1816 kUniform2RealLocation
,
1817 kUniform2DesiredLocation
,
1818 kUniform2NameWithArrayIndex
,
1823 kUniform3FakeLocation
,
1824 kUniform3RealLocation
,
1825 kUniform3DesiredLocation
,
1826 kUniform3NameWithArrayIndex
,
1829 const size_t kNumAttribs
= arraysize(kAttribs
);
1830 const size_t kNumUniforms
= arraysize(kUniforms
);
1831 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1833 program
->Link(NULL
, Program::kCountOnlyStaticallyUsed
,
1834 base::Bind(&ShaderCacheCb
));
1835 SetupExpectationsForClearingUniforms(kUniforms
, kNumUniforms
);
1836 manager_
.ClearUniforms(program
);
1840 TEST_F(ProgramManagerWithShaderTest
, BindUniformLocation
) {
1841 const GLuint kVShaderClientId
= 2001;
1842 const GLuint kFShaderClientId
= 2002;
1843 const GLuint kVShaderServiceId
= 3001;
1844 const GLuint kFShaderServiceId
= 3002;
1846 const GLint kUniform1DesiredLocation
= 10;
1847 const GLint kUniform2DesiredLocation
= -1;
1848 const GLint kUniform3DesiredLocation
= 5;
1850 Shader
* vshader
= shader_manager_
.CreateShader(
1851 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1852 ASSERT_TRUE(vshader
!= NULL
);
1853 TestHelper::SetShaderStates(gl_
.get(), vshader
, true);
1854 Shader
* fshader
= shader_manager_
.CreateShader(
1855 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1856 ASSERT_TRUE(fshader
!= NULL
);
1857 TestHelper::SetShaderStates(gl_
.get(), fshader
, true);
1858 static const GLuint kClientProgramId
= 1234;
1859 static const GLuint kServiceProgramId
= 5679;
1860 Program
* program
= manager_
.CreateProgram(
1861 kClientProgramId
, kServiceProgramId
);
1862 ASSERT_TRUE(program
!= NULL
);
1863 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1864 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1865 EXPECT_TRUE(program
->SetUniformLocationBinding(
1866 kUniform1Name
, kUniform1DesiredLocation
));
1867 EXPECT_TRUE(program
->SetUniformLocationBinding(
1868 kUniform3Name
, kUniform3DesiredLocation
));
1870 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1871 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1872 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1873 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1875 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1879 kUniform1FakeLocation
,
1880 kUniform1RealLocation
,
1881 kUniform1DesiredLocation
,
1887 kUniform2FakeLocation
,
1888 kUniform2RealLocation
,
1889 kUniform2DesiredLocation
,
1890 kUniform2NameWithArrayIndex
,
1895 kUniform3FakeLocation
,
1896 kUniform3RealLocation
,
1897 kUniform3DesiredLocation
,
1898 kUniform3NameWithArrayIndex
,
1902 const size_t kNumAttribs
= arraysize(kAttribs
);
1903 const size_t kNumUniforms
= arraysize(kUniforms
);
1904 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1906 program
->Link(NULL
, Program::kCountOnlyStaticallyUsed
,
1907 base::Bind(&ShaderCacheCb
));
1909 EXPECT_EQ(kUniform1DesiredLocation
,
1910 program
->GetUniformFakeLocation(kUniform1Name
));
1911 EXPECT_EQ(kUniform3DesiredLocation
,
1912 program
->GetUniformFakeLocation(kUniform3Name
));
1913 EXPECT_EQ(kUniform3DesiredLocation
,
1914 program
->GetUniformFakeLocation(kUniform3NameWithArrayIndex
));
1917 class ProgramManagerWithCacheTest
: public GpuServiceTest
{
1919 static const GLuint kClientProgramId
= 1;
1920 static const GLuint kServiceProgramId
= 10;
1921 static const GLuint kVertexShaderClientId
= 2;
1922 static const GLuint kFragmentShaderClientId
= 20;
1923 static const GLuint kVertexShaderServiceId
= 3;
1924 static const GLuint kFragmentShaderServiceId
= 30;
1926 ProgramManagerWithCacheTest()
1927 : cache_(new MockProgramCache()),
1928 manager_(cache_
.get(), kMaxVaryingVectors
),
1929 vertex_shader_(NULL
),
1930 fragment_shader_(NULL
),
1933 ~ProgramManagerWithCacheTest() override
{
1934 manager_
.Destroy(false);
1935 shader_manager_
.Destroy(false);
1939 void SetUp() override
{
1940 GpuServiceTest::SetUp();
1942 vertex_shader_
= shader_manager_
.CreateShader(
1943 kVertexShaderClientId
, kVertexShaderServiceId
, GL_VERTEX_SHADER
);
1944 fragment_shader_
= shader_manager_
.CreateShader(
1945 kFragmentShaderClientId
, kFragmentShaderServiceId
, GL_FRAGMENT_SHADER
);
1946 ASSERT_TRUE(vertex_shader_
!= NULL
);
1947 ASSERT_TRUE(fragment_shader_
!= NULL
);
1948 vertex_shader_
->set_source("lka asjf bjajsdfj");
1949 fragment_shader_
->set_source("lka asjf a fasgag 3rdsf3 bjajsdfj");
1951 program_
= manager_
.CreateProgram(
1952 kClientProgramId
, kServiceProgramId
);
1953 ASSERT_TRUE(program_
!= NULL
);
1955 program_
->AttachShader(&shader_manager_
, vertex_shader_
);
1956 program_
->AttachShader(&shader_manager_
, fragment_shader_
);
1959 void SetShadersCompiled() {
1960 TestHelper::SetShaderStates(gl_
.get(), vertex_shader_
, true);
1961 TestHelper::SetShaderStates(gl_
.get(), fragment_shader_
, true);
1964 void SetProgramCached() {
1965 cache_
->LinkedProgramCacheSuccess(
1966 vertex_shader_
->source(),
1967 fragment_shader_
->source(),
1968 &program_
->bind_attrib_location_map(),
1969 program_
->transform_feedback_varyings(),
1970 program_
->transform_feedback_buffer_mode());
1973 void SetExpectationsForProgramCached() {
1974 SetExpectationsForProgramCached(program_
,
1979 void SetExpectationsForProgramCached(
1981 Shader
* vertex_shader
,
1982 Shader
* fragment_shader
) {
1983 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
1984 program
->service_id(),
1987 &program
->bind_attrib_location_map(),
1988 program_
->transform_feedback_varyings(),
1989 program_
->transform_feedback_buffer_mode(),
1993 void SetExpectationsForNotCachingProgram() {
1994 SetExpectationsForNotCachingProgram(program_
,
1999 void SetExpectationsForNotCachingProgram(
2001 Shader
* vertex_shader
,
2002 Shader
* fragment_shader
) {
2003 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
2004 program
->service_id(),
2007 &program
->bind_attrib_location_map(),
2008 program_
->transform_feedback_varyings(),
2009 program_
->transform_feedback_buffer_mode(),
2013 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result
) {
2014 SetExpectationsForProgramLoad(kServiceProgramId
,
2021 void SetExpectationsForProgramLoad(
2022 GLuint service_program_id
,
2024 Shader
* vertex_shader
,
2025 Shader
* fragment_shader
,
2026 ProgramCache::ProgramLoadResult result
) {
2027 EXPECT_CALL(*cache_
.get(),
2028 LoadLinkedProgram(service_program_id
,
2031 &program
->bind_attrib_location_map(),
2032 program_
->transform_feedback_varyings(),
2033 program_
->transform_feedback_buffer_mode(),
2035 .WillOnce(Return(result
));
2038 void SetExpectationsForProgramLoadSuccess() {
2039 SetExpectationsForProgramLoadSuccess(kServiceProgramId
);
2042 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id
) {
2043 TestHelper::SetupProgramSuccessExpectations(gl_
.get(),
2048 service_program_id
);
2051 void SetExpectationsForProgramLink() {
2052 SetExpectationsForProgramLink(kServiceProgramId
);
2055 void SetExpectationsForProgramLink(GLuint service_program_id
) {
2056 TestHelper::SetupShader(gl_
.get(), NULL
, 0, NULL
, 0, service_program_id
);
2057 if (gfx::g_driver_gl
.ext
.b_GL_ARB_get_program_binary
) {
2058 EXPECT_CALL(*gl_
.get(),
2059 ProgramParameteri(service_program_id
,
2060 PROGRAM_BINARY_RETRIEVABLE_HINT
,
2065 void SetExpectationsForSuccessCompile(
2066 const Shader
* shader
) {
2067 const GLuint shader_id
= shader
->service_id();
2068 const char* src
= shader
->source().c_str();
2069 EXPECT_CALL(*gl_
.get(),
2070 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(1);
2071 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
2072 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
2073 .WillOnce(SetArgPointee
<2>(GL_TRUE
));
2076 void SetExpectationsForNoCompile(const Shader
* shader
) {
2077 const GLuint shader_id
= shader
->service_id();
2078 const char* src
= shader
->source().c_str();
2079 EXPECT_CALL(*gl_
.get(),
2080 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(0);
2081 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(0);
2082 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
2086 void SetExpectationsForErrorCompile(const Shader
* shader
) {
2087 const GLuint shader_id
= shader
->service_id();
2088 const char* src
= shader
->source().c_str();
2089 EXPECT_CALL(*gl_
.get(),
2090 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(1);
2091 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
2092 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
2093 .WillOnce(SetArgPointee
<2>(GL_FALSE
));
2094 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_INFO_LOG_LENGTH
, _
))
2095 .WillOnce(SetArgPointee
<2>(0));
2096 EXPECT_CALL(*gl_
.get(), GetShaderInfoLog(shader_id
, 0, _
, _
))
2100 scoped_ptr
<MockProgramCache
> cache_
;
2101 ProgramManager manager_
;
2103 Shader
* vertex_shader_
;
2104 Shader
* fragment_shader_
;
2106 ShaderManager shader_manager_
;
2109 // GCC requires these declarations, but MSVC requires they not be present
2110 #ifndef COMPILER_MSVC
2111 const GLuint
ProgramManagerWithCacheTest::kClientProgramId
;
2112 const GLuint
ProgramManagerWithCacheTest::kServiceProgramId
;
2113 const GLuint
ProgramManagerWithCacheTest::kVertexShaderClientId
;
2114 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderClientId
;
2115 const GLuint
ProgramManagerWithCacheTest::kVertexShaderServiceId
;
2116 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderServiceId
;
2119 TEST_F(ProgramManagerWithCacheTest
, CacheProgramOnSuccessfulLink
) {
2120 SetShadersCompiled();
2121 SetExpectationsForProgramLink();
2122 SetExpectationsForProgramCached();
2123 EXPECT_TRUE(program_
->Link(NULL
, Program::kCountOnlyStaticallyUsed
,
2124 base::Bind(&ShaderCacheCb
)));
2127 TEST_F(ProgramManagerWithCacheTest
, LoadProgramOnProgramCacheHit
) {
2128 SetShadersCompiled();
2131 SetExpectationsForNoCompile(vertex_shader_
);
2132 SetExpectationsForNoCompile(fragment_shader_
);
2133 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS
);
2134 SetExpectationsForNotCachingProgram();
2135 SetExpectationsForProgramLoadSuccess();
2137 EXPECT_TRUE(program_
->Link(NULL
, Program::kCountOnlyStaticallyUsed
,
2138 base::Bind(&ShaderCacheCb
)));
2141 } // namespace gles2