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::SetArgumentPointee
;
32 using ::testing::StrEq
;
38 const uint32 kMaxVaryingVectors
= 8;
40 void ShaderCacheCb(const std::string
& key
, const std::string
& shader
) {}
41 } // namespace anonymous
43 class ProgramManagerTest
: public GpuServiceTest
{
45 ProgramManagerTest() : manager_(NULL
, kMaxVaryingVectors
) { }
46 virtual ~ProgramManagerTest() {
47 manager_
.Destroy(false);
51 ProgramManager manager_
;
54 TEST_F(ProgramManagerTest
, Basic
) {
55 const GLuint kClient1Id
= 1;
56 const GLuint kService1Id
= 11;
57 const GLuint kClient2Id
= 2;
58 // Check we can create program.
59 manager_
.CreateProgram(kClient1Id
, kService1Id
);
60 // Check program got created.
61 Program
* program1
= manager_
.GetProgram(kClient1Id
);
62 ASSERT_TRUE(program1
!= NULL
);
64 EXPECT_TRUE(manager_
.GetClientId(program1
->service_id(), &client_id
));
65 EXPECT_EQ(kClient1Id
, client_id
);
66 // Check we get nothing for a non-existent program.
67 EXPECT_TRUE(manager_
.GetProgram(kClient2Id
) == NULL
);
70 TEST_F(ProgramManagerTest
, Destroy
) {
71 const GLuint kClient1Id
= 1;
72 const GLuint kService1Id
= 11;
73 // Check we can create program.
74 Program
* program0
= manager_
.CreateProgram(kClient1Id
, kService1Id
);
75 ASSERT_TRUE(program0
!= NULL
);
76 // Check program got created.
77 Program
* program1
= manager_
.GetProgram(kClient1Id
);
78 ASSERT_EQ(program0
, program1
);
79 EXPECT_CALL(*gl_
, DeleteProgram(kService1Id
))
81 .RetiresOnSaturation();
82 manager_
.Destroy(true);
83 // Check the resources were released.
84 program1
= manager_
.GetProgram(kClient1Id
);
85 ASSERT_TRUE(program1
== NULL
);
88 TEST_F(ProgramManagerTest
, DeleteBug
) {
89 ShaderManager shader_manager
;
90 const GLuint kClient1Id
= 1;
91 const GLuint kClient2Id
= 2;
92 const GLuint kService1Id
= 11;
93 const GLuint kService2Id
= 12;
94 // Check we can create program.
95 scoped_refptr
<Program
> program1(
96 manager_
.CreateProgram(kClient1Id
, kService1Id
));
97 scoped_refptr
<Program
> program2(
98 manager_
.CreateProgram(kClient2Id
, kService2Id
));
99 // Check program got created.
100 ASSERT_TRUE(program1
.get());
101 ASSERT_TRUE(program2
.get());
102 manager_
.UseProgram(program1
.get());
103 manager_
.MarkAsDeleted(&shader_manager
, program1
.get());
104 // Program will be deleted when last ref is released.
105 EXPECT_CALL(*gl_
, DeleteProgram(kService2Id
))
107 .RetiresOnSaturation();
108 manager_
.MarkAsDeleted(&shader_manager
, program2
.get());
109 EXPECT_TRUE(manager_
.IsOwned(program1
.get()));
110 EXPECT_FALSE(manager_
.IsOwned(program2
.get()));
113 TEST_F(ProgramManagerTest
, Program
) {
114 const GLuint kClient1Id
= 1;
115 const GLuint kService1Id
= 11;
116 // Check we can create program.
117 Program
* program1
= manager_
.CreateProgram(
118 kClient1Id
, kService1Id
);
119 ASSERT_TRUE(program1
);
120 EXPECT_EQ(kService1Id
, program1
->service_id());
121 EXPECT_FALSE(program1
->InUse());
122 EXPECT_FALSE(program1
->IsValid());
123 EXPECT_FALSE(program1
->IsDeleted());
124 EXPECT_FALSE(program1
->CanLink());
125 EXPECT_TRUE(program1
->log_info() == NULL
);
128 class ProgramManagerWithShaderTest
: public GpuServiceTest
{
130 ProgramManagerWithShaderTest()
131 : manager_(NULL
, kMaxVaryingVectors
), program_(NULL
) {
134 virtual ~ProgramManagerWithShaderTest() {
135 manager_
.Destroy(false);
136 shader_manager_
.Destroy(false);
139 static const GLint kNumVertexAttribs
= 16;
141 static const GLuint kClientProgramId
= 123;
142 static const GLuint kServiceProgramId
= 456;
143 static const GLuint kVertexShaderClientId
= 201;
144 static const GLuint kFragmentShaderClientId
= 202;
145 static const GLuint kVertexShaderServiceId
= 301;
146 static const GLuint kFragmentShaderServiceId
= 302;
148 static const char* kAttrib1Name
;
149 static const char* kAttrib2Name
;
150 static const char* kAttrib3Name
;
151 static const GLint kAttrib1Size
= 1;
152 static const GLint kAttrib2Size
= 1;
153 static const GLint kAttrib3Size
= 1;
154 static const int kAttrib1Precision
= SH_PRECISION_MEDIUMP
;
155 static const int kAttrib2Precision
= SH_PRECISION_HIGHP
;
156 static const int kAttrib3Precision
= SH_PRECISION_LOWP
;
157 static const int kAttribStaticUse
= 0;
158 static const GLint kAttrib1Location
= 0;
159 static const GLint kAttrib2Location
= 1;
160 static const GLint kAttrib3Location
= 2;
161 static const GLenum kAttrib1Type
= GL_FLOAT_VEC4
;
162 static const GLenum kAttrib2Type
= GL_FLOAT_VEC2
;
163 static const GLenum kAttrib3Type
= GL_FLOAT_VEC3
;
164 static const GLint kInvalidAttribLocation
= 30;
165 static const GLint kBadAttribIndex
= kNumVertexAttribs
;
167 static const char* kUniform1Name
;
168 static const char* kUniform2Name
;
169 static const char* kUniform3BadName
;
170 static const char* kUniform3GoodName
;
171 static const GLint kUniform1Size
= 1;
172 static const GLint kUniform2Size
= 3;
173 static const GLint kUniform3Size
= 2;
174 static const int kUniform1Precision
= SH_PRECISION_LOWP
;
175 static const int kUniform2Precision
= SH_PRECISION_MEDIUMP
;
176 static const int kUniform3Precision
= SH_PRECISION_HIGHP
;
177 static const int kUniform1StaticUse
= 1;
178 static const int kUniform2StaticUse
= 1;
179 static const int kUniform3StaticUse
= 1;
180 static const GLint kUniform1FakeLocation
= 0; // These are hard coded
181 static const GLint kUniform2FakeLocation
= 1; // to match
182 static const GLint kUniform3FakeLocation
= 2; // ProgramManager.
183 static const GLint kUniform1RealLocation
= 11;
184 static const GLint kUniform2RealLocation
= 22;
185 static const GLint kUniform3RealLocation
= 33;
186 static const GLint kUniform1DesiredLocation
= -1;
187 static const GLint kUniform2DesiredLocation
= -1;
188 static const GLint kUniform3DesiredLocation
= -1;
189 static const GLenum kUniform1Type
= GL_FLOAT_VEC4
;
190 static const GLenum kUniform2Type
= GL_INT_VEC2
;
191 static const GLenum kUniform3Type
= GL_FLOAT_VEC3
;
192 static const GLint kInvalidUniformLocation
= 30;
193 static const GLint kBadUniformIndex
= 1000;
195 static const size_t kNumAttribs
;
196 static const size_t kNumUniforms
;
199 typedef TestHelper::AttribInfo AttribInfo
;
200 typedef TestHelper::UniformInfo UniformInfo
;
214 VarCategory category
;
217 virtual void SetUp() {
218 GpuServiceTest::SetUp();
220 SetupDefaultShaderExpectations();
222 Shader
* vertex_shader
= shader_manager_
.CreateShader(
223 kVertexShaderClientId
, kVertexShaderServiceId
, GL_VERTEX_SHADER
);
224 Shader
* fragment_shader
=
225 shader_manager_
.CreateShader(
226 kFragmentShaderClientId
, kFragmentShaderServiceId
,
228 ASSERT_TRUE(vertex_shader
!= NULL
);
229 ASSERT_TRUE(fragment_shader
!= NULL
);
230 vertex_shader
->SetStatus(true, NULL
, NULL
);
231 fragment_shader
->SetStatus(true, NULL
, NULL
);
233 program_
= manager_
.CreateProgram(
234 kClientProgramId
, kServiceProgramId
);
235 ASSERT_TRUE(program_
!= NULL
);
237 program_
->AttachShader(&shader_manager_
, vertex_shader
);
238 program_
->AttachShader(&shader_manager_
, fragment_shader
);
239 program_
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
240 base::Bind(&ShaderCacheCb
));
243 void SetupShader(AttribInfo
* attribs
, size_t num_attribs
,
244 UniformInfo
* uniforms
, size_t num_uniforms
,
246 TestHelper::SetupShader(
247 gl_
.get(), attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
250 void SetupDefaultShaderExpectations() {
251 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
255 void SetupExpectationsForClearingUniforms(
256 UniformInfo
* uniforms
, size_t num_uniforms
) {
257 TestHelper::SetupExpectationsForClearingUniforms(
258 gl_
.get(), uniforms
, num_uniforms
);
261 // Return true if link status matches expected_link_status
262 bool LinkAsExpected(Program
* program
,
263 bool expected_link_status
) {
264 GLuint service_id
= program
->service_id();
265 if (expected_link_status
) {
266 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
269 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
270 base::Bind(&ShaderCacheCb
));
272 program
->GetProgramiv(GL_LINK_STATUS
, &link_status
);
273 return (static_cast<bool>(link_status
) == expected_link_status
);
276 Program
* SetupShaderVariableTest(const VarInfo
* vertex_variables
,
277 size_t vertex_variable_size
,
278 const VarInfo
* fragment_variables
,
279 size_t fragment_variable_size
) {
281 const GLuint kVShaderClientId
= 1;
282 const GLuint kVShaderServiceId
= 11;
283 const GLuint kFShaderClientId
= 2;
284 const GLuint kFShaderServiceId
= 12;
286 MockShaderTranslator vertex_shader_translator
;
287 ShaderTranslator::VariableMap vertex_attrib_map
;
288 ShaderTranslator::VariableMap vertex_uniform_map
;
289 ShaderTranslator::VariableMap vertex_varying_map
;
290 for (size_t ii
= 0; ii
< vertex_variable_size
; ++ii
) {
291 ShaderTranslator::VariableMap
* map
= NULL
;
292 switch (vertex_variables
[ii
].category
) {
294 map
= &vertex_attrib_map
;
297 map
= &vertex_uniform_map
;
300 map
= &vertex_varying_map
;
305 (*map
)[vertex_variables
[ii
].name
] =
306 ShaderTranslator::VariableInfo(vertex_variables
[ii
].type
,
307 vertex_variables
[ii
].size
,
308 vertex_variables
[ii
].precision
,
309 vertex_variables
[ii
].static_use
,
310 vertex_variables
[ii
].name
);
312 ShaderTranslator::NameMap vertex_name_map
;
313 EXPECT_CALL(vertex_shader_translator
, attrib_map())
314 .WillRepeatedly(ReturnRef(vertex_attrib_map
));
315 EXPECT_CALL(vertex_shader_translator
, uniform_map())
316 .WillRepeatedly(ReturnRef(vertex_uniform_map
));
317 EXPECT_CALL(vertex_shader_translator
, varying_map())
318 .WillRepeatedly(ReturnRef(vertex_varying_map
));
319 EXPECT_CALL(vertex_shader_translator
, name_map())
320 .WillRepeatedly(ReturnRef(vertex_name_map
));
322 MockShaderTranslator frag_shader_translator
;
323 ShaderTranslator::VariableMap frag_attrib_map
;
324 ShaderTranslator::VariableMap frag_uniform_map
;
325 ShaderTranslator::VariableMap frag_varying_map
;
326 for (size_t ii
= 0; ii
< fragment_variable_size
; ++ii
) {
327 ShaderTranslator::VariableMap
* map
= NULL
;
328 switch (fragment_variables
[ii
].category
) {
330 map
= &frag_attrib_map
;
333 map
= &frag_uniform_map
;
336 map
= &frag_varying_map
;
341 (*map
)[fragment_variables
[ii
].name
] =
342 ShaderTranslator::VariableInfo(fragment_variables
[ii
].type
,
343 fragment_variables
[ii
].size
,
344 fragment_variables
[ii
].precision
,
345 fragment_variables
[ii
].static_use
,
346 fragment_variables
[ii
].name
);
348 ShaderTranslator::NameMap frag_name_map
;
349 EXPECT_CALL(frag_shader_translator
, attrib_map())
350 .WillRepeatedly(ReturnRef(frag_attrib_map
));
351 EXPECT_CALL(frag_shader_translator
, uniform_map())
352 .WillRepeatedly(ReturnRef(frag_uniform_map
));
353 EXPECT_CALL(frag_shader_translator
, varying_map())
354 .WillRepeatedly(ReturnRef(frag_varying_map
));
355 EXPECT_CALL(frag_shader_translator
, name_map())
356 .WillRepeatedly(ReturnRef(frag_name_map
));
358 // Check we can create shader.
359 Shader
* vshader
= shader_manager_
.CreateShader(
360 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
361 Shader
* fshader
= shader_manager_
.CreateShader(
362 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
363 // Check shader got created.
364 EXPECT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
366 vshader
->SetStatus(true, "", &vertex_shader_translator
);
367 fshader
->SetStatus(true, "", &frag_shader_translator
);
370 const GLuint kClientProgramId
= 6666;
371 const GLuint kServiceProgramId
= 8888;
373 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
374 EXPECT_TRUE(program
!= NULL
);
375 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
376 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
380 static AttribInfo kAttribs
[];
381 static UniformInfo kUniforms
[];
383 ProgramManager manager_
;
385 ShaderManager shader_manager_
;
388 ProgramManagerWithShaderTest::AttribInfo
389 ProgramManagerWithShaderTest::kAttribs
[] = {
390 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
391 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
392 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
395 // GCC requires these declarations, but MSVC requires they not be present
396 #ifndef COMPILER_MSVC
397 const GLint
ProgramManagerWithShaderTest::kNumVertexAttribs
;
398 const GLuint
ProgramManagerWithShaderTest::kClientProgramId
;
399 const GLuint
ProgramManagerWithShaderTest::kServiceProgramId
;
400 const GLuint
ProgramManagerWithShaderTest::kVertexShaderClientId
;
401 const GLuint
ProgramManagerWithShaderTest::kFragmentShaderClientId
;
402 const GLuint
ProgramManagerWithShaderTest::kVertexShaderServiceId
;
403 const GLuint
ProgramManagerWithShaderTest::kFragmentShaderServiceId
;
404 const GLint
ProgramManagerWithShaderTest::kAttrib1Size
;
405 const GLint
ProgramManagerWithShaderTest::kAttrib2Size
;
406 const GLint
ProgramManagerWithShaderTest::kAttrib3Size
;
407 const GLint
ProgramManagerWithShaderTest::kAttrib1Location
;
408 const GLint
ProgramManagerWithShaderTest::kAttrib2Location
;
409 const GLint
ProgramManagerWithShaderTest::kAttrib3Location
;
410 const GLenum
ProgramManagerWithShaderTest::kAttrib1Type
;
411 const GLenum
ProgramManagerWithShaderTest::kAttrib2Type
;
412 const GLenum
ProgramManagerWithShaderTest::kAttrib3Type
;
413 const GLint
ProgramManagerWithShaderTest::kInvalidAttribLocation
;
414 const GLint
ProgramManagerWithShaderTest::kBadAttribIndex
;
415 const GLint
ProgramManagerWithShaderTest::kUniform1Size
;
416 const GLint
ProgramManagerWithShaderTest::kUniform2Size
;
417 const GLint
ProgramManagerWithShaderTest::kUniform3Size
;
418 const GLint
ProgramManagerWithShaderTest::kUniform1FakeLocation
;
419 const GLint
ProgramManagerWithShaderTest::kUniform2FakeLocation
;
420 const GLint
ProgramManagerWithShaderTest::kUniform3FakeLocation
;
421 const GLint
ProgramManagerWithShaderTest::kUniform1RealLocation
;
422 const GLint
ProgramManagerWithShaderTest::kUniform2RealLocation
;
423 const GLint
ProgramManagerWithShaderTest::kUniform3RealLocation
;
424 const GLint
ProgramManagerWithShaderTest::kUniform1DesiredLocation
;
425 const GLint
ProgramManagerWithShaderTest::kUniform2DesiredLocation
;
426 const GLint
ProgramManagerWithShaderTest::kUniform3DesiredLocation
;
427 const GLenum
ProgramManagerWithShaderTest::kUniform1Type
;
428 const GLenum
ProgramManagerWithShaderTest::kUniform2Type
;
429 const GLenum
ProgramManagerWithShaderTest::kUniform3Type
;
430 const GLint
ProgramManagerWithShaderTest::kInvalidUniformLocation
;
431 const GLint
ProgramManagerWithShaderTest::kBadUniformIndex
;
434 const size_t ProgramManagerWithShaderTest::kNumAttribs
=
435 arraysize(ProgramManagerWithShaderTest::kAttribs
);
437 ProgramManagerWithShaderTest::UniformInfo
438 ProgramManagerWithShaderTest::kUniforms
[] = {
442 kUniform1FakeLocation
,
443 kUniform1RealLocation
,
444 kUniform1DesiredLocation
,
450 kUniform2FakeLocation
,
451 kUniform2RealLocation
,
452 kUniform2DesiredLocation
,
458 kUniform3FakeLocation
,
459 kUniform3RealLocation
,
460 kUniform3DesiredLocation
,
465 const size_t ProgramManagerWithShaderTest::kNumUniforms
=
466 arraysize(ProgramManagerWithShaderTest::kUniforms
);
468 const char* ProgramManagerWithShaderTest::kAttrib1Name
= "attrib1";
469 const char* ProgramManagerWithShaderTest::kAttrib2Name
= "attrib2";
470 const char* ProgramManagerWithShaderTest::kAttrib3Name
= "attrib3";
471 const char* ProgramManagerWithShaderTest::kUniform1Name
= "uniform1";
472 // Correctly has array spec.
473 const char* ProgramManagerWithShaderTest::kUniform2Name
= "uniform2[0]";
474 // Incorrectly missing array spec.
475 const char* ProgramManagerWithShaderTest::kUniform3BadName
= "uniform3";
476 const char* ProgramManagerWithShaderTest::kUniform3GoodName
= "uniform3[0]";
478 TEST_F(ProgramManagerWithShaderTest
, GetAttribInfos
) {
479 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
480 ASSERT_TRUE(program
!= NULL
);
481 const Program::AttribInfoVector
& infos
=
482 program
->GetAttribInfos();
483 ASSERT_EQ(kNumAttribs
, infos
.size());
484 for (size_t ii
= 0; ii
< kNumAttribs
; ++ii
) {
485 const Program::VertexAttrib
& info
= infos
[ii
];
486 const AttribInfo
& expected
= kAttribs
[ii
];
487 EXPECT_EQ(expected
.size
, info
.size
);
488 EXPECT_EQ(expected
.type
, info
.type
);
489 EXPECT_EQ(expected
.location
, info
.location
);
490 EXPECT_STREQ(expected
.name
, info
.name
.c_str());
494 TEST_F(ProgramManagerWithShaderTest
, GetAttribInfo
) {
495 const GLint kValidIndex
= 1;
496 const GLint kInvalidIndex
= 1000;
497 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
498 ASSERT_TRUE(program
!= NULL
);
499 const Program::VertexAttrib
* info
=
500 program
->GetAttribInfo(kValidIndex
);
501 ASSERT_TRUE(info
!= NULL
);
502 EXPECT_EQ(kAttrib2Size
, info
->size
);
503 EXPECT_EQ(kAttrib2Type
, info
->type
);
504 EXPECT_EQ(kAttrib2Location
, info
->location
);
505 EXPECT_STREQ(kAttrib2Name
, info
->name
.c_str());
506 EXPECT_TRUE(program
->GetAttribInfo(kInvalidIndex
) == NULL
);
509 TEST_F(ProgramManagerWithShaderTest
, GetAttribLocation
) {
510 const char* kInvalidName
= "foo";
511 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
512 ASSERT_TRUE(program
!= NULL
);
513 EXPECT_EQ(kAttrib2Location
, program
->GetAttribLocation(kAttrib2Name
));
514 EXPECT_EQ(-1, program
->GetAttribLocation(kInvalidName
));
517 TEST_F(ProgramManagerWithShaderTest
, GetUniformInfo
) {
518 const GLint kInvalidIndex
= 1000;
519 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
520 ASSERT_TRUE(program
!= NULL
);
521 const Program::UniformInfo
* info
=
522 program
->GetUniformInfo(0);
523 ASSERT_TRUE(info
!= NULL
);
524 EXPECT_EQ(kUniform1Size
, info
->size
);
525 EXPECT_EQ(kUniform1Type
, info
->type
);
526 EXPECT_EQ(kUniform1RealLocation
, info
->element_locations
[0]);
527 EXPECT_STREQ(kUniform1Name
, info
->name
.c_str());
528 info
= program
->GetUniformInfo(1);
529 ASSERT_TRUE(info
!= NULL
);
530 EXPECT_EQ(kUniform2Size
, info
->size
);
531 EXPECT_EQ(kUniform2Type
, info
->type
);
532 EXPECT_EQ(kUniform2RealLocation
, info
->element_locations
[0]);
533 EXPECT_STREQ(kUniform2Name
, info
->name
.c_str());
534 info
= program
->GetUniformInfo(2);
535 // We emulate certain OpenGL drivers by supplying the name without
536 // the array spec. Our implementation should correctly add the required spec.
537 ASSERT_TRUE(info
!= NULL
);
538 EXPECT_EQ(kUniform3Size
, info
->size
);
539 EXPECT_EQ(kUniform3Type
, info
->type
);
540 EXPECT_EQ(kUniform3RealLocation
, info
->element_locations
[0]);
541 EXPECT_STREQ(kUniform3GoodName
, info
->name
.c_str());
542 EXPECT_TRUE(program
->GetUniformInfo(kInvalidIndex
) == NULL
);
545 TEST_F(ProgramManagerWithShaderTest
, AttachDetachShader
) {
546 static const GLuint kClientProgramId
= 124;
547 static const GLuint kServiceProgramId
= 457;
548 Program
* program
= manager_
.CreateProgram(
549 kClientProgramId
, kServiceProgramId
);
550 ASSERT_TRUE(program
!= NULL
);
551 EXPECT_FALSE(program
->CanLink());
552 const GLuint kVShaderClientId
= 2001;
553 const GLuint kFShaderClientId
= 2002;
554 const GLuint kVShaderServiceId
= 3001;
555 const GLuint kFShaderServiceId
= 3002;
556 Shader
* vshader
= shader_manager_
.CreateShader(
557 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
558 ASSERT_TRUE(vshader
!= NULL
);
559 vshader
->SetStatus(true, "", NULL
);
560 Shader
* fshader
= shader_manager_
.CreateShader(
561 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
562 ASSERT_TRUE(fshader
!= NULL
);
563 fshader
->SetStatus(true, "", NULL
);
564 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
565 EXPECT_FALSE(program
->CanLink());
566 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
567 EXPECT_TRUE(program
->CanLink());
568 program
->DetachShader(&shader_manager_
, vshader
);
569 EXPECT_FALSE(program
->CanLink());
570 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
571 EXPECT_TRUE(program
->CanLink());
572 program
->DetachShader(&shader_manager_
, fshader
);
573 EXPECT_FALSE(program
->CanLink());
574 EXPECT_FALSE(program
->AttachShader(&shader_manager_
, vshader
));
575 EXPECT_FALSE(program
->CanLink());
576 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
577 EXPECT_TRUE(program
->CanLink());
578 vshader
->SetStatus(false, "", NULL
);
579 EXPECT_FALSE(program
->CanLink());
580 vshader
->SetStatus(true, "", NULL
);
581 EXPECT_TRUE(program
->CanLink());
582 fshader
->SetStatus(false, "", NULL
);
583 EXPECT_FALSE(program
->CanLink());
584 fshader
->SetStatus(true, "", NULL
);
585 EXPECT_TRUE(program
->CanLink());
586 EXPECT_TRUE(program
->DetachShader(&shader_manager_
, fshader
));
587 EXPECT_FALSE(program
->DetachShader(&shader_manager_
, fshader
));
590 TEST_F(ProgramManagerWithShaderTest
, GetUniformFakeLocation
) {
591 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
592 ASSERT_TRUE(program
!= NULL
);
593 // Emulate the situation that uniform3[1] isn't used and optimized out by
594 // a driver, so it's location is -1.
595 Program::UniformInfo
* uniform
= const_cast<Program::UniformInfo
*>(
596 program
->GetUniformInfo(2));
597 ASSERT_TRUE(uniform
!= NULL
&& kUniform3Size
== 2);
598 EXPECT_EQ(kUniform3Size
, uniform
->size
);
599 uniform
->element_locations
[1] = -1;
600 EXPECT_EQ(kUniform1FakeLocation
,
601 program
->GetUniformFakeLocation(kUniform1Name
));
602 EXPECT_EQ(kUniform2FakeLocation
,
603 program
->GetUniformFakeLocation(kUniform2Name
));
604 EXPECT_EQ(kUniform3FakeLocation
,
605 program
->GetUniformFakeLocation(kUniform3BadName
));
606 // Check we can get uniform2 as "uniform2" even though the name is
608 EXPECT_EQ(kUniform2FakeLocation
,
609 program
->GetUniformFakeLocation("uniform2"));
610 // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
611 // returning "uniform3"
612 EXPECT_EQ(kUniform3FakeLocation
,
613 program
->GetUniformFakeLocation(kUniform3GoodName
));
614 // Check that we can get the locations of the array elements > 1
615 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation
, 1),
616 program
->GetUniformFakeLocation("uniform2[1]"));
617 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation
, 2),
618 program
->GetUniformFakeLocation("uniform2[2]"));
619 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform2[3]"));
620 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform3[1]"));
621 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform3[2]"));
624 TEST_F(ProgramManagerWithShaderTest
, GetUniformInfoByFakeLocation
) {
625 const GLint kInvalidLocation
= 1234;
626 const Program::UniformInfo
* info
;
627 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
628 GLint real_location
= -1;
629 GLint array_index
= -1;
630 ASSERT_TRUE(program
!= NULL
);
631 info
= program
->GetUniformInfoByFakeLocation(
632 kUniform2FakeLocation
, &real_location
, &array_index
);
633 EXPECT_EQ(kUniform2RealLocation
, real_location
);
634 EXPECT_EQ(0, array_index
);
635 ASSERT_TRUE(info
!= NULL
);
636 EXPECT_EQ(kUniform2Type
, info
->type
);
639 info
= program
->GetUniformInfoByFakeLocation(
640 kInvalidLocation
, &real_location
, &array_index
);
641 EXPECT_TRUE(info
== NULL
);
642 EXPECT_EQ(-1, real_location
);
643 EXPECT_EQ(-1, array_index
);
644 GLint loc
= program
->GetUniformFakeLocation("uniform2[2]");
645 info
= program
->GetUniformInfoByFakeLocation(
646 loc
, &real_location
, &array_index
);
647 ASSERT_TRUE(info
!= NULL
);
648 EXPECT_EQ(kUniform2RealLocation
+ 2 * 2, real_location
);
649 EXPECT_EQ(2, array_index
);
652 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
653 // that start with "gl_". Our implementation catches these and does not allow
654 // them back to client.
655 TEST_F(ProgramManagerWithShaderTest
, GLDriverReturnsGLUnderscoreUniform
) {
656 static const char* kUniform2Name
= "gl_longNameWeCanCheckFor";
657 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
661 kUniform1FakeLocation
,
662 kUniform1RealLocation
,
663 kUniform1DesiredLocation
,
669 kUniform2FakeLocation
,
670 kUniform2RealLocation
,
671 kUniform2DesiredLocation
,
677 kUniform3FakeLocation
,
678 kUniform3RealLocation
,
679 kUniform3DesiredLocation
,
683 const size_t kNumUniforms
= arraysize(kUniforms
);
684 static const GLuint kClientProgramId
= 1234;
685 static const GLuint kServiceProgramId
= 5679;
686 const GLuint kVShaderClientId
= 2001;
687 const GLuint kFShaderClientId
= 2002;
688 const GLuint kVShaderServiceId
= 3001;
689 const GLuint kFShaderServiceId
= 3002;
691 kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
, kServiceProgramId
);
692 Shader
* vshader
= shader_manager_
.CreateShader(
693 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
694 ASSERT_TRUE(vshader
!= NULL
);
695 vshader
->SetStatus(true, "", NULL
);
696 Shader
* fshader
= shader_manager_
.CreateShader(
697 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
698 ASSERT_TRUE(fshader
!= NULL
);
699 fshader
->SetStatus(true, "", NULL
);
701 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
702 ASSERT_TRUE(program
!= NULL
);
703 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
704 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
705 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
706 base::Bind(&ShaderCacheCb
));
708 program
->GetProgramiv(GL_ACTIVE_ATTRIBUTES
, &value
);
710 // Check that we skipped the "gl_" uniform.
711 program
->GetProgramiv(GL_ACTIVE_UNIFORMS
, &value
);
713 // Check that our max length adds room for the array spec and is not as long
714 // as the "gl_" uniform we skipped.
715 // +4u is to account for "gl_" and NULL terminator.
716 program
->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH
, &value
);
717 EXPECT_EQ(strlen(kUniform3BadName
) + 4u, static_cast<size_t>(value
));
720 // Test the bug comparing similar array names is fixed.
721 TEST_F(ProgramManagerWithShaderTest
, SimilarArrayNames
) {
722 static const char* kUniform2Name
= "u_nameLong[0]";
723 static const char* kUniform3Name
= "u_name[0]";
724 static const GLint kUniform2Size
= 2;
725 static const GLint kUniform3Size
= 2;
726 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
730 kUniform1FakeLocation
,
731 kUniform1RealLocation
,
732 kUniform1DesiredLocation
,
738 kUniform2FakeLocation
,
739 kUniform2RealLocation
,
740 kUniform2DesiredLocation
,
746 kUniform3FakeLocation
,
747 kUniform3RealLocation
,
748 kUniform3DesiredLocation
,
752 const size_t kNumUniforms
= arraysize(kUniforms
);
753 static const GLuint kClientProgramId
= 1234;
754 static const GLuint kServiceProgramId
= 5679;
755 const GLuint kVShaderClientId
= 2001;
756 const GLuint kFShaderClientId
= 2002;
757 const GLuint kVShaderServiceId
= 3001;
758 const GLuint kFShaderServiceId
= 3002;
760 kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
, kServiceProgramId
);
761 Shader
* vshader
= shader_manager_
.CreateShader(
762 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
763 ASSERT_TRUE(vshader
!= NULL
);
764 vshader
->SetStatus(true, "", NULL
);
765 Shader
* fshader
= shader_manager_
.CreateShader(
766 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
767 ASSERT_TRUE(fshader
!= NULL
);
768 fshader
->SetStatus(true, "", NULL
);
770 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
771 ASSERT_TRUE(program
!= NULL
);
772 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
773 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
774 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
775 base::Bind(&ShaderCacheCb
));
777 // Check that we get the correct locations.
778 EXPECT_EQ(kUniform2FakeLocation
,
779 program
->GetUniformFakeLocation(kUniform2Name
));
780 EXPECT_EQ(kUniform3FakeLocation
,
781 program
->GetUniformFakeLocation(kUniform3Name
));
784 // Some GL drivers incorrectly return the wrong type. For example they return
785 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
786 TEST_F(ProgramManagerWithShaderTest
, GLDriverReturnsWrongTypeInfo
) {
787 static GLenum kAttrib2BadType
= GL_FLOAT_VEC2
;
788 static GLenum kAttrib2GoodType
= GL_FLOAT_MAT2
;
789 static GLenum kUniform2BadType
= GL_FLOAT_VEC3
;
790 static GLenum kUniform2GoodType
= GL_FLOAT_MAT3
;
791 MockShaderTranslator shader_translator
;
792 ShaderTranslator::VariableMap attrib_map
;
793 ShaderTranslator::VariableMap uniform_map
;
794 ShaderTranslator::VariableMap varying_map
;
795 attrib_map
[kAttrib1Name
] = ShaderTranslatorInterface::VariableInfo(
796 kAttrib1Type
, kAttrib1Size
, kAttrib1Precision
,
797 kAttribStaticUse
, kAttrib1Name
);
798 attrib_map
[kAttrib2Name
] = ShaderTranslatorInterface::VariableInfo(
799 kAttrib2GoodType
, kAttrib2Size
, kAttrib2Precision
,
800 kAttribStaticUse
, kAttrib2Name
);
801 attrib_map
[kAttrib3Name
] = ShaderTranslatorInterface::VariableInfo(
802 kAttrib3Type
, kAttrib3Size
, kAttrib3Precision
,
803 kAttribStaticUse
, kAttrib3Name
);
804 uniform_map
[kUniform1Name
] = ShaderTranslatorInterface::VariableInfo(
805 kUniform1Type
, kUniform1Size
, kUniform1Precision
,
806 kUniform1StaticUse
, kUniform1Name
);
807 uniform_map
[kUniform2Name
] = ShaderTranslatorInterface::VariableInfo(
808 kUniform2GoodType
, kUniform2Size
, kUniform2Precision
,
809 kUniform2StaticUse
, kUniform2Name
);
810 uniform_map
[kUniform3GoodName
] = ShaderTranslatorInterface::VariableInfo(
811 kUniform3Type
, kUniform3Size
, kUniform3Precision
,
812 kUniform3StaticUse
, kUniform3GoodName
);
813 EXPECT_CALL(shader_translator
, attrib_map())
814 .WillRepeatedly(ReturnRef(attrib_map
));
815 EXPECT_CALL(shader_translator
, uniform_map())
816 .WillRepeatedly(ReturnRef(uniform_map
));
817 EXPECT_CALL(shader_translator
, varying_map())
818 .WillRepeatedly(ReturnRef(varying_map
));
819 ShaderTranslator::NameMap name_map
;
820 EXPECT_CALL(shader_translator
, name_map())
821 .WillRepeatedly(ReturnRef(name_map
));
822 const GLuint kVShaderClientId
= 2001;
823 const GLuint kFShaderClientId
= 2002;
824 const GLuint kVShaderServiceId
= 3001;
825 const GLuint kFShaderServiceId
= 3002;
826 Shader
* vshader
= shader_manager_
.CreateShader(
827 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
828 ASSERT_TRUE(vshader
!= NULL
);
829 vshader
->SetStatus(true, "", &shader_translator
);
830 Shader
* fshader
= shader_manager_
.CreateShader(
831 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
832 ASSERT_TRUE(fshader
!= NULL
);
833 fshader
->SetStatus(true, "", &shader_translator
);
834 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
835 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
836 { kAttrib2Name
, kAttrib2Size
, kAttrib2BadType
, kAttrib2Location
, },
837 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
839 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
843 kUniform1FakeLocation
,
844 kUniform1RealLocation
,
845 kUniform1DesiredLocation
,
851 kUniform2FakeLocation
,
852 kUniform2RealLocation
,
853 kUniform2DesiredLocation
,
859 kUniform3FakeLocation
,
860 kUniform3RealLocation
,
861 kUniform3DesiredLocation
,
865 const size_t kNumAttribs
= arraysize(kAttribs
);
866 const size_t kNumUniforms
= arraysize(kUniforms
);
867 static const GLuint kClientProgramId
= 1234;
868 static const GLuint kServiceProgramId
= 5679;
869 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
871 Program
* program
= manager_
.CreateProgram(
872 kClientProgramId
, kServiceProgramId
);
873 ASSERT_TRUE(program
!= NULL
);
874 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
875 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
876 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
877 base::Bind(&ShaderCacheCb
));
878 // Check that we got the good type, not the bad.
880 for (unsigned index
= 0; index
< kNumAttribs
; ++index
) {
881 const Program::VertexAttrib
* attrib_info
=
882 program
->GetAttribInfo(index
);
883 ASSERT_TRUE(attrib_info
!= NULL
);
884 ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.find(
886 ASSERT_TRUE(it
!= attrib_map
.end());
887 EXPECT_EQ(it
->first
, attrib_info
->name
);
888 EXPECT_EQ(static_cast<GLenum
>(it
->second
.type
), attrib_info
->type
);
889 EXPECT_EQ(it
->second
.size
, attrib_info
->size
);
890 EXPECT_EQ(it
->second
.name
, attrib_info
->name
);
893 for (unsigned index
= 0; index
< kNumUniforms
; ++index
) {
894 const Program::UniformInfo
* uniform_info
=
895 program
->GetUniformInfo(index
);
896 ASSERT_TRUE(uniform_info
!= NULL
);
897 ShaderTranslator::VariableMap::const_iterator it
= uniform_map
.find(
899 ASSERT_TRUE(it
!= uniform_map
.end());
900 EXPECT_EQ(it
->first
, uniform_info
->name
);
901 EXPECT_EQ(static_cast<GLenum
>(it
->second
.type
), uniform_info
->type
);
902 EXPECT_EQ(it
->second
.size
, uniform_info
->size
);
903 EXPECT_EQ(it
->second
.name
, uniform_info
->name
);
907 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoUseCount
) {
908 static const GLuint kClientProgramId
= 124;
909 static const GLuint kServiceProgramId
= 457;
910 Program
* program
= manager_
.CreateProgram(
911 kClientProgramId
, kServiceProgramId
);
912 ASSERT_TRUE(program
!= NULL
);
913 EXPECT_FALSE(program
->CanLink());
914 const GLuint kVShaderClientId
= 2001;
915 const GLuint kFShaderClientId
= 2002;
916 const GLuint kVShaderServiceId
= 3001;
917 const GLuint kFShaderServiceId
= 3002;
918 Shader
* vshader
= shader_manager_
.CreateShader(
919 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
920 ASSERT_TRUE(vshader
!= NULL
);
921 vshader
->SetStatus(true, "", NULL
);
922 Shader
* fshader
= shader_manager_
.CreateShader(
923 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
924 ASSERT_TRUE(fshader
!= NULL
);
925 fshader
->SetStatus(true, "", NULL
);
926 EXPECT_FALSE(vshader
->InUse());
927 EXPECT_FALSE(fshader
->InUse());
928 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
929 EXPECT_TRUE(vshader
->InUse());
930 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
931 EXPECT_TRUE(fshader
->InUse());
932 EXPECT_TRUE(program
->CanLink());
933 EXPECT_FALSE(program
->InUse());
934 EXPECT_FALSE(program
->IsDeleted());
935 manager_
.UseProgram(program
);
936 EXPECT_TRUE(program
->InUse());
937 manager_
.UseProgram(program
);
938 EXPECT_TRUE(program
->InUse());
939 manager_
.MarkAsDeleted(&shader_manager_
, program
);
940 EXPECT_TRUE(program
->IsDeleted());
941 Program
* info2
= manager_
.GetProgram(kClientProgramId
);
942 EXPECT_EQ(program
, info2
);
943 manager_
.UnuseProgram(&shader_manager_
, program
);
944 EXPECT_TRUE(program
->InUse());
945 // this should delete the info.
946 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
948 .RetiresOnSaturation();
949 manager_
.UnuseProgram(&shader_manager_
, program
);
950 info2
= manager_
.GetProgram(kClientProgramId
);
951 EXPECT_TRUE(info2
== NULL
);
952 EXPECT_FALSE(vshader
->InUse());
953 EXPECT_FALSE(fshader
->InUse());
956 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoUseCount2
) {
957 static const GLuint kClientProgramId
= 124;
958 static const GLuint kServiceProgramId
= 457;
959 Program
* program
= manager_
.CreateProgram(
960 kClientProgramId
, kServiceProgramId
);
961 ASSERT_TRUE(program
!= NULL
);
962 EXPECT_FALSE(program
->CanLink());
963 const GLuint kVShaderClientId
= 2001;
964 const GLuint kFShaderClientId
= 2002;
965 const GLuint kVShaderServiceId
= 3001;
966 const GLuint kFShaderServiceId
= 3002;
967 Shader
* vshader
= shader_manager_
.CreateShader(
968 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
969 ASSERT_TRUE(vshader
!= NULL
);
970 vshader
->SetStatus(true, "", NULL
);
971 Shader
* fshader
= shader_manager_
.CreateShader(
972 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
973 ASSERT_TRUE(fshader
!= NULL
);
974 fshader
->SetStatus(true, "", NULL
);
975 EXPECT_FALSE(vshader
->InUse());
976 EXPECT_FALSE(fshader
->InUse());
977 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
978 EXPECT_TRUE(vshader
->InUse());
979 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
980 EXPECT_TRUE(fshader
->InUse());
981 EXPECT_TRUE(program
->CanLink());
982 EXPECT_FALSE(program
->InUse());
983 EXPECT_FALSE(program
->IsDeleted());
984 manager_
.UseProgram(program
);
985 EXPECT_TRUE(program
->InUse());
986 manager_
.UseProgram(program
);
987 EXPECT_TRUE(program
->InUse());
988 manager_
.UnuseProgram(&shader_manager_
, program
);
989 EXPECT_TRUE(program
->InUse());
990 manager_
.UnuseProgram(&shader_manager_
, program
);
991 EXPECT_FALSE(program
->InUse());
992 Program
* info2
= manager_
.GetProgram(kClientProgramId
);
993 EXPECT_EQ(program
, info2
);
994 // this should delete the program.
995 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
997 .RetiresOnSaturation();
998 manager_
.MarkAsDeleted(&shader_manager_
, program
);
999 info2
= manager_
.GetProgram(kClientProgramId
);
1000 EXPECT_TRUE(info2
== NULL
);
1001 EXPECT_FALSE(vshader
->InUse());
1002 EXPECT_FALSE(fshader
->InUse());
1005 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoGetProgramInfo
) {
1006 CommonDecoder::Bucket bucket
;
1007 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1008 ASSERT_TRUE(program
!= NULL
);
1009 program
->GetProgramInfo(&manager_
, &bucket
);
1010 ProgramInfoHeader
* header
=
1011 bucket
.GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
1012 ASSERT_TRUE(header
!= NULL
);
1013 EXPECT_EQ(1u, header
->link_status
);
1014 EXPECT_EQ(arraysize(kAttribs
), header
->num_attribs
);
1015 EXPECT_EQ(arraysize(kUniforms
), header
->num_uniforms
);
1016 const ProgramInput
* inputs
= bucket
.GetDataAs
<const ProgramInput
*>(
1018 sizeof(ProgramInput
) * (header
->num_attribs
+ header
->num_uniforms
));
1019 ASSERT_TRUE(inputs
!= NULL
);
1020 const ProgramInput
* input
= inputs
;
1021 // TODO(gman): Don't assume these are in order.
1022 for (uint32 ii
= 0; ii
< header
->num_attribs
; ++ii
) {
1023 const AttribInfo
& expected
= kAttribs
[ii
];
1024 EXPECT_EQ(expected
.size
, input
->size
);
1025 EXPECT_EQ(expected
.type
, input
->type
);
1026 const int32
* location
= bucket
.GetDataAs
<const int32
*>(
1027 input
->location_offset
, sizeof(int32
));
1028 ASSERT_TRUE(location
!= NULL
);
1029 EXPECT_EQ(expected
.location
, *location
);
1030 const char* name_buf
= bucket
.GetDataAs
<const char*>(
1031 input
->name_offset
, input
->name_length
);
1032 ASSERT_TRUE(name_buf
!= NULL
);
1033 std::string
name(name_buf
, input
->name_length
);
1034 EXPECT_STREQ(expected
.name
, name
.c_str());
1037 // TODO(gman): Don't assume these are in order.
1038 for (uint32 ii
= 0; ii
< header
->num_uniforms
; ++ii
) {
1039 const UniformInfo
& expected
= kUniforms
[ii
];
1040 EXPECT_EQ(expected
.size
, input
->size
);
1041 EXPECT_EQ(expected
.type
, input
->type
);
1042 const int32
* locations
= bucket
.GetDataAs
<const int32
*>(
1043 input
->location_offset
, sizeof(int32
) * input
->size
);
1044 ASSERT_TRUE(locations
!= NULL
);
1045 for (int32 jj
= 0; jj
< input
->size
; ++jj
) {
1047 ProgramManager::MakeFakeLocation(expected
.fake_location
, jj
),
1050 const char* name_buf
= bucket
.GetDataAs
<const char*>(
1051 input
->name_offset
, input
->name_length
);
1052 ASSERT_TRUE(name_buf
!= NULL
);
1053 std::string
name(name_buf
, input
->name_length
);
1054 EXPECT_STREQ(expected
.good_name
, name
.c_str());
1057 EXPECT_EQ(header
->num_attribs
+ header
->num_uniforms
,
1058 static_cast<uint32
>(input
- inputs
));
1061 // Some drivers optimize out unused uniform array elements, so their
1062 // location would be -1.
1063 TEST_F(ProgramManagerWithShaderTest
, UnusedUniformArrayElements
) {
1064 CommonDecoder::Bucket bucket
;
1065 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1066 ASSERT_TRUE(program
!= NULL
);
1067 // Emulate the situation that only the first element has a valid location.
1068 // TODO(zmo): Don't assume these are in order.
1069 for (size_t ii
= 0; ii
< arraysize(kUniforms
); ++ii
) {
1070 Program::UniformInfo
* uniform
= const_cast<Program::UniformInfo
*>(
1071 program
->GetUniformInfo(ii
));
1072 ASSERT_TRUE(uniform
!= NULL
);
1073 EXPECT_EQ(static_cast<size_t>(kUniforms
[ii
].size
),
1074 uniform
->element_locations
.size());
1075 for (GLsizei jj
= 1; jj
< uniform
->size
; ++jj
)
1076 uniform
->element_locations
[jj
] = -1;
1078 program
->GetProgramInfo(&manager_
, &bucket
);
1079 ProgramInfoHeader
* header
=
1080 bucket
.GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
1081 ASSERT_TRUE(header
!= NULL
);
1082 EXPECT_EQ(1u, header
->link_status
);
1083 EXPECT_EQ(arraysize(kAttribs
), header
->num_attribs
);
1084 EXPECT_EQ(arraysize(kUniforms
), header
->num_uniforms
);
1085 const ProgramInput
* inputs
= bucket
.GetDataAs
<const ProgramInput
*>(
1087 sizeof(ProgramInput
) * (header
->num_attribs
+ header
->num_uniforms
));
1088 ASSERT_TRUE(inputs
!= NULL
);
1089 const ProgramInput
* input
= inputs
+ header
->num_attribs
;
1090 for (uint32 ii
= 0; ii
< header
->num_uniforms
; ++ii
) {
1091 const UniformInfo
& expected
= kUniforms
[ii
];
1092 EXPECT_EQ(expected
.size
, input
->size
);
1093 const int32
* locations
= bucket
.GetDataAs
<const int32
*>(
1094 input
->location_offset
, sizeof(int32
) * input
->size
);
1095 ASSERT_TRUE(locations
!= NULL
);
1097 ProgramManager::MakeFakeLocation(expected
.fake_location
, 0),
1099 for (int32 jj
= 1; jj
< input
->size
; ++jj
)
1100 EXPECT_EQ(-1, locations
[jj
]);
1105 TEST_F(ProgramManagerWithShaderTest
, BindAttribLocationConflicts
) {
1107 const GLuint kVShaderClientId
= 1;
1108 const GLuint kVShaderServiceId
= 11;
1109 const GLuint kFShaderClientId
= 2;
1110 const GLuint kFShaderServiceId
= 12;
1111 MockShaderTranslator shader_translator
;
1112 ShaderTranslator::VariableMap attrib_map
;
1113 for (uint32 ii
= 0; ii
< kNumAttribs
; ++ii
) {
1114 attrib_map
[kAttribs
[ii
].name
] = ShaderTranslatorInterface::VariableInfo(
1117 SH_PRECISION_MEDIUMP
,
1121 ShaderTranslator::VariableMap uniform_map
;
1122 ShaderTranslator::VariableMap varying_map
;
1123 EXPECT_CALL(shader_translator
, attrib_map())
1124 .WillRepeatedly(ReturnRef(attrib_map
));
1125 EXPECT_CALL(shader_translator
, uniform_map())
1126 .WillRepeatedly(ReturnRef(uniform_map
));
1127 EXPECT_CALL(shader_translator
, varying_map())
1128 .WillRepeatedly(ReturnRef(varying_map
));
1129 ShaderTranslator::NameMap name_map
;
1130 EXPECT_CALL(shader_translator
, name_map())
1131 .WillRepeatedly(ReturnRef(name_map
));
1132 // Check we can create shader.
1133 Shader
* vshader
= shader_manager_
.CreateShader(
1134 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1135 Shader
* fshader
= shader_manager_
.CreateShader(
1136 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1137 // Check shader got created.
1138 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1140 vshader
->SetStatus(true, "", &shader_translator
);
1141 // Check attrib infos got copied.
1142 for (ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.begin();
1143 it
!= attrib_map
.end(); ++it
) {
1144 const Shader::VariableInfo
* variable_info
=
1145 vshader
->GetAttribInfo(it
->first
);
1146 ASSERT_TRUE(variable_info
!= NULL
);
1147 EXPECT_EQ(it
->second
.type
, variable_info
->type
);
1148 EXPECT_EQ(it
->second
.size
, variable_info
->size
);
1149 EXPECT_EQ(it
->second
.precision
, variable_info
->precision
);
1150 EXPECT_EQ(it
->second
.static_use
, variable_info
->static_use
);
1151 EXPECT_EQ(it
->second
.name
, variable_info
->name
);
1153 fshader
->SetStatus(true, "", NULL
);
1156 const GLuint kClientProgramId
= 6666;
1157 const GLuint kServiceProgramId
= 8888;
1159 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1160 ASSERT_TRUE(program
!= NULL
);
1161 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1162 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1164 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1165 EXPECT_TRUE(LinkAsExpected(program
, true));
1167 program
->SetAttribLocationBinding(kAttrib1Name
, 0);
1168 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1169 EXPECT_TRUE(LinkAsExpected(program
, true));
1171 program
->SetAttribLocationBinding("xxx", 0);
1172 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1173 EXPECT_TRUE(LinkAsExpected(program
, true));
1175 program
->SetAttribLocationBinding(kAttrib2Name
, 1);
1176 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1177 EXPECT_TRUE(LinkAsExpected(program
, true));
1179 program
->SetAttribLocationBinding(kAttrib2Name
, 0);
1180 EXPECT_TRUE(program
->DetectAttribLocationBindingConflicts());
1181 EXPECT_TRUE(LinkAsExpected(program
, false));
1184 TEST_F(ProgramManagerWithShaderTest
, UniformsPrecisionMismatch
) {
1186 const GLuint kVShaderClientId
= 1;
1187 const GLuint kVShaderServiceId
= 11;
1188 const GLuint kFShaderClientId
= 2;
1189 const GLuint kFShaderServiceId
= 12;
1191 MockShaderTranslator vertex_shader_translator
;
1192 ShaderTranslator::VariableMap vertex_attrib_map
;
1193 ShaderTranslator::VariableMap vertex_uniform_map
;
1194 vertex_uniform_map
["a"] = ShaderTranslator::VariableInfo(
1195 1, 3, SH_PRECISION_MEDIUMP
, 1, "a");
1196 ShaderTranslator::VariableMap vertex_varying_map
;
1197 ShaderTranslator::NameMap vertex_name_map
;
1198 EXPECT_CALL(vertex_shader_translator
, attrib_map())
1199 .WillRepeatedly(ReturnRef(vertex_attrib_map
));
1200 EXPECT_CALL(vertex_shader_translator
, uniform_map())
1201 .WillRepeatedly(ReturnRef(vertex_uniform_map
));
1202 EXPECT_CALL(vertex_shader_translator
, varying_map())
1203 .WillRepeatedly(ReturnRef(vertex_varying_map
));
1204 EXPECT_CALL(vertex_shader_translator
, name_map())
1205 .WillRepeatedly(ReturnRef(vertex_name_map
));
1207 MockShaderTranslator frag_shader_translator
;
1208 ShaderTranslator::VariableMap frag_attrib_map
;
1209 ShaderTranslator::VariableMap frag_uniform_map
;
1210 frag_uniform_map
["a"] = ShaderTranslator::VariableInfo(
1211 1, 3, SH_PRECISION_LOWP
, 1, "a");
1212 ShaderTranslator::VariableMap frag_varying_map
;
1213 ShaderTranslator::NameMap frag_name_map
;
1214 EXPECT_CALL(frag_shader_translator
, attrib_map())
1215 .WillRepeatedly(ReturnRef(frag_attrib_map
));
1216 EXPECT_CALL(frag_shader_translator
, uniform_map())
1217 .WillRepeatedly(ReturnRef(frag_uniform_map
));
1218 EXPECT_CALL(frag_shader_translator
, varying_map())
1219 .WillRepeatedly(ReturnRef(frag_varying_map
));
1220 EXPECT_CALL(frag_shader_translator
, name_map())
1221 .WillRepeatedly(ReturnRef(frag_name_map
));
1223 // Check we can create shader.
1224 Shader
* vshader
= shader_manager_
.CreateShader(
1225 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1226 Shader
* fshader
= shader_manager_
.CreateShader(
1227 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1228 // Check shader got created.
1229 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1231 vshader
->SetStatus(true, "", &vertex_shader_translator
);
1232 fshader
->SetStatus(true, "", &frag_shader_translator
);
1235 const GLuint kClientProgramId
= 6666;
1236 const GLuint kServiceProgramId
= 8888;
1238 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1239 ASSERT_TRUE(program
!= NULL
);
1240 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1241 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1243 std::string conflicting_name
;
1245 EXPECT_TRUE(program
->DetectUniformsMismatch(&conflicting_name
));
1246 EXPECT_EQ("a", conflicting_name
);
1247 EXPECT_TRUE(LinkAsExpected(program
, false));
1250 // If a varying has different type in the vertex and fragment
1251 // shader, linking should fail.
1252 TEST_F(ProgramManagerWithShaderTest
, VaryingTypeMismatch
) {
1253 const VarInfo kVertexVarying
=
1254 { SH_FLOAT_VEC3
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1255 const VarInfo kFragmentVarying
=
1256 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1257 Program
* program
= SetupShaderVariableTest(
1258 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1260 std::string conflicting_name
;
1262 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1263 EXPECT_EQ("a", conflicting_name
);
1264 EXPECT_TRUE(LinkAsExpected(program
, false));
1267 // If a varying has different array size in the vertex and fragment
1268 // shader, linking should fail.
1269 TEST_F(ProgramManagerWithShaderTest
, VaryingArraySizeMismatch
) {
1270 const VarInfo kVertexVarying
=
1271 { SH_FLOAT
, 2, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1272 const VarInfo kFragmentVarying
=
1273 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1274 Program
* program
= SetupShaderVariableTest(
1275 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1277 std::string conflicting_name
;
1279 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1280 EXPECT_EQ("a", conflicting_name
);
1281 EXPECT_TRUE(LinkAsExpected(program
, false));
1284 // If a varying has different precision in the vertex and fragment
1285 // shader, linking should succeed.
1286 TEST_F(ProgramManagerWithShaderTest
, VaryingPrecisionMismatch
) {
1287 const VarInfo kVertexVarying
=
1288 { SH_FLOAT
, 2, SH_PRECISION_HIGHP
, 1, "a", kVarVarying
};
1289 const VarInfo kFragmentVarying
=
1290 { SH_FLOAT
, 2, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1291 Program
* program
= SetupShaderVariableTest(
1292 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1294 std::string conflicting_name
;
1296 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1297 EXPECT_TRUE(conflicting_name
.empty());
1298 EXPECT_TRUE(LinkAsExpected(program
, true));
1301 // If a varying is statically used in fragment shader but not
1302 // declared in vertex shader, link should fail.
1303 TEST_F(ProgramManagerWithShaderTest
, VaryingMissing
) {
1304 const VarInfo kFragmentVarying
=
1305 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1306 Program
* program
= SetupShaderVariableTest(
1307 NULL
, 0, &kFragmentVarying
, 1);
1309 std::string conflicting_name
;
1311 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1312 EXPECT_EQ("a", conflicting_name
);
1313 EXPECT_TRUE(LinkAsExpected(program
, false));
1316 // If a varying is declared but not statically used in fragment
1317 // shader, even if it's not declared in vertex shader, link should
1319 TEST_F(ProgramManagerWithShaderTest
, InactiveVarying
) {
1320 const VarInfo kFragmentVarying
=
1321 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
};
1322 Program
* program
= SetupShaderVariableTest(
1323 NULL
, 0, &kFragmentVarying
, 1);
1325 std::string conflicting_name
;
1327 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1328 EXPECT_TRUE(conflicting_name
.empty());
1329 EXPECT_TRUE(LinkAsExpected(program
, true));
1332 // Uniforms and attributes are both global variables, thus sharing
1333 // the same namespace. Any name conflicts should cause link
1335 TEST_F(ProgramManagerWithShaderTest
, AttribUniformNameConflict
) {
1336 const VarInfo kVertexAttribute
=
1337 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarAttribute
};
1338 const VarInfo kFragmentUniform
=
1339 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarUniform
};
1340 Program
* program
= SetupShaderVariableTest(
1341 &kVertexAttribute
, 1, &kFragmentUniform
, 1);
1343 std::string conflicting_name
;
1345 EXPECT_TRUE(program
->DetectGlobalNameConflicts(&conflicting_name
));
1346 EXPECT_EQ("a", conflicting_name
);
1347 EXPECT_TRUE(LinkAsExpected(program
, false));
1350 // Varyings go over 8 rows.
1351 TEST_F(ProgramManagerWithShaderTest
, TooManyVaryings
) {
1352 const VarInfo kVertexVaryings
[] = {
1353 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1354 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1356 const VarInfo kFragmentVaryings
[] = {
1357 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1358 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1360 Program
* program
= SetupShaderVariableTest(
1361 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1364 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1365 EXPECT_TRUE(LinkAsExpected(program
, false));
1368 // Varyings go over 8 rows but some are inactive
1369 TEST_F(ProgramManagerWithShaderTest
, TooManyInactiveVaryings
) {
1370 const VarInfo kVertexVaryings
[] = {
1371 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1372 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1374 const VarInfo kFragmentVaryings
[] = {
1375 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
},
1376 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1378 Program
* program
= SetupShaderVariableTest(
1379 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1382 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1383 EXPECT_TRUE(LinkAsExpected(program
, true));
1386 // Varyings go over 8 rows but some are inactive.
1387 // However, we still fail the check if kCountAll option is used.
1388 TEST_F(ProgramManagerWithShaderTest
, CountAllVaryingsInPacking
) {
1389 const VarInfo kVertexVaryings
[] = {
1390 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1391 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1393 const VarInfo kFragmentVaryings
[] = {
1394 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
},
1395 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1397 Program
* program
= SetupShaderVariableTest(
1398 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1400 EXPECT_FALSE(program
->CheckVaryingsPacking(Program::kCountAll
));
1403 TEST_F(ProgramManagerWithShaderTest
, ClearWithSamplerTypes
) {
1404 const GLuint kVShaderClientId
= 2001;
1405 const GLuint kFShaderClientId
= 2002;
1406 const GLuint kVShaderServiceId
= 3001;
1407 const GLuint kFShaderServiceId
= 3002;
1408 Shader
* vshader
= shader_manager_
.CreateShader(
1409 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1410 ASSERT_TRUE(vshader
!= NULL
);
1411 vshader
->SetStatus(true, NULL
, NULL
);
1412 Shader
* fshader
= shader_manager_
.CreateShader(
1413 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1414 ASSERT_TRUE(fshader
!= NULL
);
1415 fshader
->SetStatus(true, NULL
, NULL
);
1416 static const GLuint kClientProgramId
= 1234;
1417 static const GLuint kServiceProgramId
= 5679;
1418 Program
* program
= manager_
.CreateProgram(
1419 kClientProgramId
, kServiceProgramId
);
1420 ASSERT_TRUE(program
!= NULL
);
1421 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1422 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1424 static const GLenum kSamplerTypes
[] = {
1427 GL_SAMPLER_EXTERNAL_OES
,
1429 GL_SAMPLER_2D_RECT_ARB
,
1431 const size_t kNumSamplerTypes
= arraysize(kSamplerTypes
);
1432 for (size_t ii
= 0; ii
< kNumSamplerTypes
; ++ii
) {
1433 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1434 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1435 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1436 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1438 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1442 kUniform1FakeLocation
,
1443 kUniform1RealLocation
,
1444 kUniform1DesiredLocation
,
1450 kUniform2FakeLocation
,
1451 kUniform2RealLocation
,
1452 kUniform2DesiredLocation
,
1458 kUniform3FakeLocation
,
1459 kUniform3RealLocation
,
1460 kUniform3DesiredLocation
,
1464 const size_t kNumAttribs
= arraysize(kAttribs
);
1465 const size_t kNumUniforms
= arraysize(kUniforms
);
1466 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1468 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
1469 base::Bind(&ShaderCacheCb
));
1470 SetupExpectationsForClearingUniforms(kUniforms
, kNumUniforms
);
1471 manager_
.ClearUniforms(program
);
1475 TEST_F(ProgramManagerWithShaderTest
, BindUniformLocation
) {
1476 const GLuint kVShaderClientId
= 2001;
1477 const GLuint kFShaderClientId
= 2002;
1478 const GLuint kVShaderServiceId
= 3001;
1479 const GLuint kFShaderServiceId
= 3002;
1481 const GLint kUniform1DesiredLocation
= 10;
1482 const GLint kUniform2DesiredLocation
= -1;
1483 const GLint kUniform3DesiredLocation
= 5;
1485 Shader
* vshader
= shader_manager_
.CreateShader(
1486 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1487 ASSERT_TRUE(vshader
!= NULL
);
1488 vshader
->SetStatus(true, NULL
, NULL
);
1489 Shader
* fshader
= shader_manager_
.CreateShader(
1490 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1491 ASSERT_TRUE(fshader
!= NULL
);
1492 fshader
->SetStatus(true, NULL
, NULL
);
1493 static const GLuint kClientProgramId
= 1234;
1494 static const GLuint kServiceProgramId
= 5679;
1495 Program
* program
= manager_
.CreateProgram(
1496 kClientProgramId
, kServiceProgramId
);
1497 ASSERT_TRUE(program
!= NULL
);
1498 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1499 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1500 EXPECT_TRUE(program
->SetUniformLocationBinding(
1501 kUniform1Name
, kUniform1DesiredLocation
));
1502 EXPECT_TRUE(program
->SetUniformLocationBinding(
1503 kUniform3BadName
, kUniform3DesiredLocation
));
1505 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1506 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1507 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1508 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1510 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1514 kUniform1FakeLocation
,
1515 kUniform1RealLocation
,
1516 kUniform1DesiredLocation
,
1522 kUniform2FakeLocation
,
1523 kUniform2RealLocation
,
1524 kUniform2DesiredLocation
,
1530 kUniform3FakeLocation
,
1531 kUniform3RealLocation
,
1532 kUniform3DesiredLocation
,
1537 const size_t kNumAttribs
= arraysize(kAttribs
);
1538 const size_t kNumUniforms
= arraysize(kUniforms
);
1539 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1541 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
1542 base::Bind(&ShaderCacheCb
));
1544 EXPECT_EQ(kUniform1DesiredLocation
,
1545 program
->GetUniformFakeLocation(kUniform1Name
));
1546 EXPECT_EQ(kUniform3DesiredLocation
,
1547 program
->GetUniformFakeLocation(kUniform3BadName
));
1548 EXPECT_EQ(kUniform3DesiredLocation
,
1549 program
->GetUniformFakeLocation(kUniform3GoodName
));
1552 class ProgramManagerWithCacheTest
: public GpuServiceTest
{
1554 static const GLuint kClientProgramId
= 1;
1555 static const GLuint kServiceProgramId
= 10;
1556 static const GLuint kVertexShaderClientId
= 2;
1557 static const GLuint kFragmentShaderClientId
= 20;
1558 static const GLuint kVertexShaderServiceId
= 3;
1559 static const GLuint kFragmentShaderServiceId
= 30;
1561 ProgramManagerWithCacheTest()
1562 : cache_(new MockProgramCache()),
1563 manager_(cache_
.get(), kMaxVaryingVectors
),
1564 vertex_shader_(NULL
),
1565 fragment_shader_(NULL
),
1568 virtual ~ProgramManagerWithCacheTest() {
1569 manager_
.Destroy(false);
1570 shader_manager_
.Destroy(false);
1574 virtual void SetUp() {
1575 GpuServiceTest::SetUp();
1577 vertex_shader_
= shader_manager_
.CreateShader(
1578 kVertexShaderClientId
, kVertexShaderServiceId
, GL_VERTEX_SHADER
);
1579 fragment_shader_
= shader_manager_
.CreateShader(
1580 kFragmentShaderClientId
, kFragmentShaderServiceId
, GL_FRAGMENT_SHADER
);
1581 ASSERT_TRUE(vertex_shader_
!= NULL
);
1582 ASSERT_TRUE(fragment_shader_
!= NULL
);
1583 vertex_shader_
->UpdateSource("lka asjf bjajsdfj");
1584 fragment_shader_
->UpdateSource("lka asjf a fasgag 3rdsf3 bjajsdfj");
1586 program_
= manager_
.CreateProgram(
1587 kClientProgramId
, kServiceProgramId
);
1588 ASSERT_TRUE(program_
!= NULL
);
1590 program_
->AttachShader(&shader_manager_
, vertex_shader_
);
1591 program_
->AttachShader(&shader_manager_
, fragment_shader_
);
1594 void SetShadersCompiled() {
1595 vertex_shader_
->SetStatus(true, NULL
, NULL
);
1596 fragment_shader_
->SetStatus(true, NULL
, NULL
);
1599 void SetProgramCached() {
1600 cache_
->LinkedProgramCacheSuccess(
1601 vertex_shader_
->source()->c_str(),
1603 fragment_shader_
->source()->c_str(),
1605 &program_
->bind_attrib_location_map());
1608 void SetExpectationsForProgramCached() {
1609 SetExpectationsForProgramCached(program_
,
1614 void SetExpectationsForProgramCached(
1616 Shader
* vertex_shader
,
1617 Shader
* fragment_shader
) {
1618 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
1619 program
->service_id(),
1624 &program
->bind_attrib_location_map(),
1628 void SetExpectationsForNotCachingProgram() {
1629 SetExpectationsForNotCachingProgram(program_
,
1634 void SetExpectationsForNotCachingProgram(
1636 Shader
* vertex_shader
,
1637 Shader
* fragment_shader
) {
1638 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
1639 program
->service_id(),
1644 &program
->bind_attrib_location_map(),
1648 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result
) {
1649 SetExpectationsForProgramLoad(kServiceProgramId
,
1656 void SetExpectationsForProgramLoad(
1657 GLuint service_program_id
,
1659 Shader
* vertex_shader
,
1660 Shader
* fragment_shader
,
1661 ProgramCache::ProgramLoadResult result
) {
1662 EXPECT_CALL(*cache_
.get(),
1663 LoadLinkedProgram(service_program_id
,
1668 &program
->bind_attrib_location_map(),
1670 .WillOnce(Return(result
));
1673 void SetExpectationsForProgramLoadSuccess() {
1674 SetExpectationsForProgramLoadSuccess(kServiceProgramId
);
1677 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id
) {
1678 TestHelper::SetupProgramSuccessExpectations(gl_
.get(),
1683 service_program_id
);
1686 void SetExpectationsForProgramLink() {
1687 SetExpectationsForProgramLink(kServiceProgramId
);
1690 void SetExpectationsForProgramLink(GLuint service_program_id
) {
1691 TestHelper::SetupShader(gl_
.get(), NULL
, 0, NULL
, 0, service_program_id
);
1692 if (gfx::g_driver_gl
.ext
.b_GL_ARB_get_program_binary
) {
1693 EXPECT_CALL(*gl_
.get(),
1694 ProgramParameteri(service_program_id
,
1695 PROGRAM_BINARY_RETRIEVABLE_HINT
,
1700 void SetExpectationsForSuccessCompile(
1701 const Shader
* shader
) {
1702 const GLuint shader_id
= shader
->service_id();
1703 const char* src
= shader
->source()->c_str();
1704 EXPECT_CALL(*gl_
.get(),
1705 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(1);
1706 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
1707 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1708 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
));
1711 void SetExpectationsForNoCompile(const Shader
* shader
) {
1712 const GLuint shader_id
= shader
->service_id();
1713 const char* src
= shader
->source()->c_str();
1714 EXPECT_CALL(*gl_
.get(),
1715 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(0);
1716 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(0);
1717 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1721 void SetExpectationsForErrorCompile(const Shader
* shader
) {
1722 const GLuint shader_id
= shader
->service_id();
1723 const char* src
= shader
->source()->c_str();
1724 EXPECT_CALL(*gl_
.get(),
1725 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(1);
1726 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
1727 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1728 .WillOnce(SetArgumentPointee
<2>(GL_FALSE
));
1729 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_INFO_LOG_LENGTH
, _
))
1730 .WillOnce(SetArgumentPointee
<2>(0));
1731 EXPECT_CALL(*gl_
.get(), GetShaderInfoLog(shader_id
, 0, _
, _
))
1735 scoped_ptr
<MockProgramCache
> cache_
;
1736 ProgramManager manager_
;
1738 Shader
* vertex_shader_
;
1739 Shader
* fragment_shader_
;
1741 ShaderManager shader_manager_
;
1744 // GCC requires these declarations, but MSVC requires they not be present
1745 #ifndef COMPILER_MSVC
1746 const GLuint
ProgramManagerWithCacheTest::kClientProgramId
;
1747 const GLuint
ProgramManagerWithCacheTest::kServiceProgramId
;
1748 const GLuint
ProgramManagerWithCacheTest::kVertexShaderClientId
;
1749 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderClientId
;
1750 const GLuint
ProgramManagerWithCacheTest::kVertexShaderServiceId
;
1751 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderServiceId
;
1754 TEST_F(ProgramManagerWithCacheTest
, CacheProgramOnSuccessfulLink
) {
1755 SetShadersCompiled();
1756 SetExpectationsForProgramLink();
1757 SetExpectationsForProgramCached();
1758 EXPECT_TRUE(program_
->Link(NULL
, NULL
, NULL
,
1759 Program::kCountOnlyStaticallyUsed
, base::Bind(&ShaderCacheCb
)));
1762 TEST_F(ProgramManagerWithCacheTest
, LoadProgramOnProgramCacheHit
) {
1763 SetShadersCompiled();
1766 SetExpectationsForNoCompile(vertex_shader_
);
1767 SetExpectationsForNoCompile(fragment_shader_
);
1768 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS
);
1769 SetExpectationsForNotCachingProgram();
1770 SetExpectationsForProgramLoadSuccess();
1772 EXPECT_TRUE(program_
->Link(NULL
, NULL
, NULL
,
1773 Program::kCountOnlyStaticallyUsed
, base::Bind(&ShaderCacheCb
)));
1776 } // namespace gles2