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