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
;
34 // ANGLE now uses GLenum values directory for types
35 // TODO(jmadill): Delete these defines when the ANGLE
36 // roll reliably passes translator version 126
37 #if (ANGLE_SH_VERSION >= 126)
38 #define SH_FLOAT GL_FLOAT
39 #define SH_FLOAT_VEC2 GL_FLOAT_VEC2
40 #define SH_FLOAT_VEC3 GL_FLOAT_VEC3
41 #define SH_FLOAT_VEC4 GL_FLOAT_VEC4
48 const uint32 kMaxVaryingVectors
= 8;
50 void ShaderCacheCb(const std::string
& key
, const std::string
& shader
) {}
51 } // namespace anonymous
53 class ProgramManagerTest
: public GpuServiceTest
{
55 ProgramManagerTest() : manager_(NULL
, kMaxVaryingVectors
) { }
56 virtual ~ProgramManagerTest() {
57 manager_
.Destroy(false);
61 ProgramManager manager_
;
64 TEST_F(ProgramManagerTest
, Basic
) {
65 const GLuint kClient1Id
= 1;
66 const GLuint kService1Id
= 11;
67 const GLuint kClient2Id
= 2;
68 // Check we can create program.
69 manager_
.CreateProgram(kClient1Id
, kService1Id
);
70 // Check program got created.
71 Program
* program1
= manager_
.GetProgram(kClient1Id
);
72 ASSERT_TRUE(program1
!= NULL
);
74 EXPECT_TRUE(manager_
.GetClientId(program1
->service_id(), &client_id
));
75 EXPECT_EQ(kClient1Id
, client_id
);
76 // Check we get nothing for a non-existent program.
77 EXPECT_TRUE(manager_
.GetProgram(kClient2Id
) == NULL
);
80 TEST_F(ProgramManagerTest
, Destroy
) {
81 const GLuint kClient1Id
= 1;
82 const GLuint kService1Id
= 11;
83 // Check we can create program.
84 Program
* program0
= manager_
.CreateProgram(kClient1Id
, kService1Id
);
85 ASSERT_TRUE(program0
!= NULL
);
86 // Check program got created.
87 Program
* program1
= manager_
.GetProgram(kClient1Id
);
88 ASSERT_EQ(program0
, program1
);
89 EXPECT_CALL(*gl_
, DeleteProgram(kService1Id
))
91 .RetiresOnSaturation();
92 manager_
.Destroy(true);
93 // Check the resources were released.
94 program1
= manager_
.GetProgram(kClient1Id
);
95 ASSERT_TRUE(program1
== NULL
);
98 TEST_F(ProgramManagerTest
, DeleteBug
) {
99 ShaderManager shader_manager
;
100 const GLuint kClient1Id
= 1;
101 const GLuint kClient2Id
= 2;
102 const GLuint kService1Id
= 11;
103 const GLuint kService2Id
= 12;
104 // Check we can create program.
105 scoped_refptr
<Program
> program1(
106 manager_
.CreateProgram(kClient1Id
, kService1Id
));
107 scoped_refptr
<Program
> program2(
108 manager_
.CreateProgram(kClient2Id
, kService2Id
));
109 // Check program got created.
110 ASSERT_TRUE(program1
.get());
111 ASSERT_TRUE(program2
.get());
112 manager_
.UseProgram(program1
.get());
113 manager_
.MarkAsDeleted(&shader_manager
, program1
.get());
114 // Program will be deleted when last ref is released.
115 EXPECT_CALL(*gl_
, DeleteProgram(kService2Id
))
117 .RetiresOnSaturation();
118 manager_
.MarkAsDeleted(&shader_manager
, program2
.get());
119 EXPECT_TRUE(manager_
.IsOwned(program1
.get()));
120 EXPECT_FALSE(manager_
.IsOwned(program2
.get()));
123 TEST_F(ProgramManagerTest
, Program
) {
124 const GLuint kClient1Id
= 1;
125 const GLuint kService1Id
= 11;
126 // Check we can create program.
127 Program
* program1
= manager_
.CreateProgram(
128 kClient1Id
, kService1Id
);
129 ASSERT_TRUE(program1
);
130 EXPECT_EQ(kService1Id
, program1
->service_id());
131 EXPECT_FALSE(program1
->InUse());
132 EXPECT_FALSE(program1
->IsValid());
133 EXPECT_FALSE(program1
->IsDeleted());
134 EXPECT_FALSE(program1
->CanLink());
135 EXPECT_TRUE(program1
->log_info() == NULL
);
138 class ProgramManagerWithShaderTest
: public GpuServiceTest
{
140 ProgramManagerWithShaderTest()
141 : manager_(NULL
, kMaxVaryingVectors
), program_(NULL
) {
144 virtual ~ProgramManagerWithShaderTest() {
145 manager_
.Destroy(false);
146 shader_manager_
.Destroy(false);
149 static const GLint kNumVertexAttribs
= 16;
151 static const GLuint kClientProgramId
= 123;
152 static const GLuint kServiceProgramId
= 456;
153 static const GLuint kVertexShaderClientId
= 201;
154 static const GLuint kFragmentShaderClientId
= 202;
155 static const GLuint kVertexShaderServiceId
= 301;
156 static const GLuint kFragmentShaderServiceId
= 302;
158 static const char* kAttrib1Name
;
159 static const char* kAttrib2Name
;
160 static const char* kAttrib3Name
;
161 static const GLint kAttrib1Size
= 1;
162 static const GLint kAttrib2Size
= 1;
163 static const GLint kAttrib3Size
= 1;
164 static const int kAttrib1Precision
= SH_PRECISION_MEDIUMP
;
165 static const int kAttrib2Precision
= SH_PRECISION_HIGHP
;
166 static const int kAttrib3Precision
= SH_PRECISION_LOWP
;
167 static const int kAttribStaticUse
= 0;
168 static const GLint kAttrib1Location
= 0;
169 static const GLint kAttrib2Location
= 1;
170 static const GLint kAttrib3Location
= 2;
171 static const GLenum kAttrib1Type
= GL_FLOAT_VEC4
;
172 static const GLenum kAttrib2Type
= GL_FLOAT_VEC2
;
173 static const GLenum kAttrib3Type
= GL_FLOAT_VEC3
;
174 static const GLint kInvalidAttribLocation
= 30;
175 static const GLint kBadAttribIndex
= kNumVertexAttribs
;
177 static const char* kUniform1Name
;
178 static const char* kUniform2Name
;
179 static const char* kUniform3BadName
;
180 static const char* kUniform3GoodName
;
181 static const GLint kUniform1Size
= 1;
182 static const GLint kUniform2Size
= 3;
183 static const GLint kUniform3Size
= 2;
184 static const int kUniform1Precision
= SH_PRECISION_LOWP
;
185 static const int kUniform2Precision
= SH_PRECISION_MEDIUMP
;
186 static const int kUniform3Precision
= SH_PRECISION_HIGHP
;
187 static const int kUniform1StaticUse
= 1;
188 static const int kUniform2StaticUse
= 1;
189 static const int kUniform3StaticUse
= 1;
190 static const GLint kUniform1FakeLocation
= 0; // These are hard coded
191 static const GLint kUniform2FakeLocation
= 1; // to match
192 static const GLint kUniform3FakeLocation
= 2; // ProgramManager.
193 static const GLint kUniform1RealLocation
= 11;
194 static const GLint kUniform2RealLocation
= 22;
195 static const GLint kUniform3RealLocation
= 33;
196 static const GLint kUniform1DesiredLocation
= -1;
197 static const GLint kUniform2DesiredLocation
= -1;
198 static const GLint kUniform3DesiredLocation
= -1;
199 static const GLenum kUniform1Type
= GL_FLOAT_VEC4
;
200 static const GLenum kUniform2Type
= GL_INT_VEC2
;
201 static const GLenum kUniform3Type
= GL_FLOAT_VEC3
;
202 static const GLint kInvalidUniformLocation
= 30;
203 static const GLint kBadUniformIndex
= 1000;
205 static const size_t kNumAttribs
;
206 static const size_t kNumUniforms
;
209 typedef TestHelper::AttribInfo AttribInfo
;
210 typedef TestHelper::UniformInfo UniformInfo
;
224 VarCategory category
;
227 virtual void SetUp() {
228 GpuServiceTest::SetUp();
230 SetupDefaultShaderExpectations();
232 Shader
* vertex_shader
= shader_manager_
.CreateShader(
233 kVertexShaderClientId
, kVertexShaderServiceId
, GL_VERTEX_SHADER
);
234 Shader
* fragment_shader
=
235 shader_manager_
.CreateShader(
236 kFragmentShaderClientId
, kFragmentShaderServiceId
,
238 ASSERT_TRUE(vertex_shader
!= NULL
);
239 ASSERT_TRUE(fragment_shader
!= NULL
);
240 vertex_shader
->SetStatus(true, NULL
, NULL
);
241 fragment_shader
->SetStatus(true, NULL
, NULL
);
243 program_
= manager_
.CreateProgram(
244 kClientProgramId
, kServiceProgramId
);
245 ASSERT_TRUE(program_
!= NULL
);
247 program_
->AttachShader(&shader_manager_
, vertex_shader
);
248 program_
->AttachShader(&shader_manager_
, fragment_shader
);
249 program_
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
250 base::Bind(&ShaderCacheCb
));
253 void SetupShader(AttribInfo
* attribs
, size_t num_attribs
,
254 UniformInfo
* uniforms
, size_t num_uniforms
,
256 TestHelper::SetupShader(
257 gl_
.get(), attribs
, num_attribs
, uniforms
, num_uniforms
, service_id
);
260 void SetupDefaultShaderExpectations() {
261 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
265 void SetupExpectationsForClearingUniforms(
266 UniformInfo
* uniforms
, size_t num_uniforms
) {
267 TestHelper::SetupExpectationsForClearingUniforms(
268 gl_
.get(), uniforms
, num_uniforms
);
271 // Return true if link status matches expected_link_status
272 bool LinkAsExpected(Program
* program
,
273 bool expected_link_status
) {
274 GLuint service_id
= program
->service_id();
275 if (expected_link_status
) {
276 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
279 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
280 base::Bind(&ShaderCacheCb
));
282 program
->GetProgramiv(GL_LINK_STATUS
, &link_status
);
283 return (static_cast<bool>(link_status
) == expected_link_status
);
286 Program
* SetupShaderVariableTest(const VarInfo
* vertex_variables
,
287 size_t vertex_variable_size
,
288 const VarInfo
* fragment_variables
,
289 size_t fragment_variable_size
) {
291 const GLuint kVShaderClientId
= 1;
292 const GLuint kVShaderServiceId
= 11;
293 const GLuint kFShaderClientId
= 2;
294 const GLuint kFShaderServiceId
= 12;
296 MockShaderTranslator vertex_shader_translator
;
297 ShaderTranslator::VariableMap vertex_attrib_map
;
298 ShaderTranslator::VariableMap vertex_uniform_map
;
299 ShaderTranslator::VariableMap vertex_varying_map
;
300 for (size_t ii
= 0; ii
< vertex_variable_size
; ++ii
) {
301 ShaderTranslator::VariableMap
* map
= NULL
;
302 switch (vertex_variables
[ii
].category
) {
304 map
= &vertex_attrib_map
;
307 map
= &vertex_uniform_map
;
310 map
= &vertex_varying_map
;
315 (*map
)[vertex_variables
[ii
].name
] =
316 ShaderTranslator::VariableInfo(vertex_variables
[ii
].type
,
317 vertex_variables
[ii
].size
,
318 vertex_variables
[ii
].precision
,
319 vertex_variables
[ii
].static_use
,
320 vertex_variables
[ii
].name
);
322 ShaderTranslator::NameMap vertex_name_map
;
323 EXPECT_CALL(vertex_shader_translator
, attrib_map())
324 .WillRepeatedly(ReturnRef(vertex_attrib_map
));
325 EXPECT_CALL(vertex_shader_translator
, uniform_map())
326 .WillRepeatedly(ReturnRef(vertex_uniform_map
));
327 EXPECT_CALL(vertex_shader_translator
, varying_map())
328 .WillRepeatedly(ReturnRef(vertex_varying_map
));
329 EXPECT_CALL(vertex_shader_translator
, name_map())
330 .WillRepeatedly(ReturnRef(vertex_name_map
));
332 MockShaderTranslator frag_shader_translator
;
333 ShaderTranslator::VariableMap frag_attrib_map
;
334 ShaderTranslator::VariableMap frag_uniform_map
;
335 ShaderTranslator::VariableMap frag_varying_map
;
336 for (size_t ii
= 0; ii
< fragment_variable_size
; ++ii
) {
337 ShaderTranslator::VariableMap
* map
= NULL
;
338 switch (fragment_variables
[ii
].category
) {
340 map
= &frag_attrib_map
;
343 map
= &frag_uniform_map
;
346 map
= &frag_varying_map
;
351 (*map
)[fragment_variables
[ii
].name
] =
352 ShaderTranslator::VariableInfo(fragment_variables
[ii
].type
,
353 fragment_variables
[ii
].size
,
354 fragment_variables
[ii
].precision
,
355 fragment_variables
[ii
].static_use
,
356 fragment_variables
[ii
].name
);
358 ShaderTranslator::NameMap frag_name_map
;
359 EXPECT_CALL(frag_shader_translator
, attrib_map())
360 .WillRepeatedly(ReturnRef(frag_attrib_map
));
361 EXPECT_CALL(frag_shader_translator
, uniform_map())
362 .WillRepeatedly(ReturnRef(frag_uniform_map
));
363 EXPECT_CALL(frag_shader_translator
, varying_map())
364 .WillRepeatedly(ReturnRef(frag_varying_map
));
365 EXPECT_CALL(frag_shader_translator
, name_map())
366 .WillRepeatedly(ReturnRef(frag_name_map
));
368 // Check we can create shader.
369 Shader
* vshader
= shader_manager_
.CreateShader(
370 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
371 Shader
* fshader
= shader_manager_
.CreateShader(
372 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
373 // Check shader got created.
374 EXPECT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
376 vshader
->SetStatus(true, "", &vertex_shader_translator
);
377 fshader
->SetStatus(true, "", &frag_shader_translator
);
380 const GLuint kClientProgramId
= 6666;
381 const GLuint kServiceProgramId
= 8888;
383 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
384 EXPECT_TRUE(program
!= NULL
);
385 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
386 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
390 static AttribInfo kAttribs
[];
391 static UniformInfo kUniforms
[];
393 ProgramManager manager_
;
395 ShaderManager shader_manager_
;
398 ProgramManagerWithShaderTest::AttribInfo
399 ProgramManagerWithShaderTest::kAttribs
[] = {
400 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
401 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
402 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
405 // GCC requires these declarations, but MSVC requires they not be present
406 #ifndef COMPILER_MSVC
407 const GLint
ProgramManagerWithShaderTest::kNumVertexAttribs
;
408 const GLuint
ProgramManagerWithShaderTest::kClientProgramId
;
409 const GLuint
ProgramManagerWithShaderTest::kServiceProgramId
;
410 const GLuint
ProgramManagerWithShaderTest::kVertexShaderClientId
;
411 const GLuint
ProgramManagerWithShaderTest::kFragmentShaderClientId
;
412 const GLuint
ProgramManagerWithShaderTest::kVertexShaderServiceId
;
413 const GLuint
ProgramManagerWithShaderTest::kFragmentShaderServiceId
;
414 const GLint
ProgramManagerWithShaderTest::kAttrib1Size
;
415 const GLint
ProgramManagerWithShaderTest::kAttrib2Size
;
416 const GLint
ProgramManagerWithShaderTest::kAttrib3Size
;
417 const GLint
ProgramManagerWithShaderTest::kAttrib1Location
;
418 const GLint
ProgramManagerWithShaderTest::kAttrib2Location
;
419 const GLint
ProgramManagerWithShaderTest::kAttrib3Location
;
420 const GLenum
ProgramManagerWithShaderTest::kAttrib1Type
;
421 const GLenum
ProgramManagerWithShaderTest::kAttrib2Type
;
422 const GLenum
ProgramManagerWithShaderTest::kAttrib3Type
;
423 const GLint
ProgramManagerWithShaderTest::kInvalidAttribLocation
;
424 const GLint
ProgramManagerWithShaderTest::kBadAttribIndex
;
425 const GLint
ProgramManagerWithShaderTest::kUniform1Size
;
426 const GLint
ProgramManagerWithShaderTest::kUniform2Size
;
427 const GLint
ProgramManagerWithShaderTest::kUniform3Size
;
428 const GLint
ProgramManagerWithShaderTest::kUniform1FakeLocation
;
429 const GLint
ProgramManagerWithShaderTest::kUniform2FakeLocation
;
430 const GLint
ProgramManagerWithShaderTest::kUniform3FakeLocation
;
431 const GLint
ProgramManagerWithShaderTest::kUniform1RealLocation
;
432 const GLint
ProgramManagerWithShaderTest::kUniform2RealLocation
;
433 const GLint
ProgramManagerWithShaderTest::kUniform3RealLocation
;
434 const GLint
ProgramManagerWithShaderTest::kUniform1DesiredLocation
;
435 const GLint
ProgramManagerWithShaderTest::kUniform2DesiredLocation
;
436 const GLint
ProgramManagerWithShaderTest::kUniform3DesiredLocation
;
437 const GLenum
ProgramManagerWithShaderTest::kUniform1Type
;
438 const GLenum
ProgramManagerWithShaderTest::kUniform2Type
;
439 const GLenum
ProgramManagerWithShaderTest::kUniform3Type
;
440 const GLint
ProgramManagerWithShaderTest::kInvalidUniformLocation
;
441 const GLint
ProgramManagerWithShaderTest::kBadUniformIndex
;
444 const size_t ProgramManagerWithShaderTest::kNumAttribs
=
445 arraysize(ProgramManagerWithShaderTest::kAttribs
);
447 ProgramManagerWithShaderTest::UniformInfo
448 ProgramManagerWithShaderTest::kUniforms
[] = {
452 kUniform1FakeLocation
,
453 kUniform1RealLocation
,
454 kUniform1DesiredLocation
,
460 kUniform2FakeLocation
,
461 kUniform2RealLocation
,
462 kUniform2DesiredLocation
,
468 kUniform3FakeLocation
,
469 kUniform3RealLocation
,
470 kUniform3DesiredLocation
,
475 const size_t ProgramManagerWithShaderTest::kNumUniforms
=
476 arraysize(ProgramManagerWithShaderTest::kUniforms
);
478 const char* ProgramManagerWithShaderTest::kAttrib1Name
= "attrib1";
479 const char* ProgramManagerWithShaderTest::kAttrib2Name
= "attrib2";
480 const char* ProgramManagerWithShaderTest::kAttrib3Name
= "attrib3";
481 const char* ProgramManagerWithShaderTest::kUniform1Name
= "uniform1";
482 // Correctly has array spec.
483 const char* ProgramManagerWithShaderTest::kUniform2Name
= "uniform2[0]";
484 // Incorrectly missing array spec.
485 const char* ProgramManagerWithShaderTest::kUniform3BadName
= "uniform3";
486 const char* ProgramManagerWithShaderTest::kUniform3GoodName
= "uniform3[0]";
488 TEST_F(ProgramManagerWithShaderTest
, GetAttribInfos
) {
489 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
490 ASSERT_TRUE(program
!= NULL
);
491 const Program::AttribInfoVector
& infos
=
492 program
->GetAttribInfos();
493 ASSERT_EQ(kNumAttribs
, infos
.size());
494 for (size_t ii
= 0; ii
< kNumAttribs
; ++ii
) {
495 const Program::VertexAttrib
& info
= infos
[ii
];
496 const AttribInfo
& expected
= kAttribs
[ii
];
497 EXPECT_EQ(expected
.size
, info
.size
);
498 EXPECT_EQ(expected
.type
, info
.type
);
499 EXPECT_EQ(expected
.location
, info
.location
);
500 EXPECT_STREQ(expected
.name
, info
.name
.c_str());
504 TEST_F(ProgramManagerWithShaderTest
, GetAttribInfo
) {
505 const GLint kValidIndex
= 1;
506 const GLint kInvalidIndex
= 1000;
507 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
508 ASSERT_TRUE(program
!= NULL
);
509 const Program::VertexAttrib
* info
=
510 program
->GetAttribInfo(kValidIndex
);
511 ASSERT_TRUE(info
!= NULL
);
512 EXPECT_EQ(kAttrib2Size
, info
->size
);
513 EXPECT_EQ(kAttrib2Type
, info
->type
);
514 EXPECT_EQ(kAttrib2Location
, info
->location
);
515 EXPECT_STREQ(kAttrib2Name
, info
->name
.c_str());
516 EXPECT_TRUE(program
->GetAttribInfo(kInvalidIndex
) == NULL
);
519 TEST_F(ProgramManagerWithShaderTest
, GetAttribLocation
) {
520 const char* kInvalidName
= "foo";
521 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
522 ASSERT_TRUE(program
!= NULL
);
523 EXPECT_EQ(kAttrib2Location
, program
->GetAttribLocation(kAttrib2Name
));
524 EXPECT_EQ(-1, program
->GetAttribLocation(kInvalidName
));
527 TEST_F(ProgramManagerWithShaderTest
, GetUniformInfo
) {
528 const GLint kInvalidIndex
= 1000;
529 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
530 ASSERT_TRUE(program
!= NULL
);
531 const Program::UniformInfo
* info
=
532 program
->GetUniformInfo(0);
533 ASSERT_TRUE(info
!= NULL
);
534 EXPECT_EQ(kUniform1Size
, info
->size
);
535 EXPECT_EQ(kUniform1Type
, info
->type
);
536 EXPECT_EQ(kUniform1RealLocation
, info
->element_locations
[0]);
537 EXPECT_STREQ(kUniform1Name
, info
->name
.c_str());
538 info
= program
->GetUniformInfo(1);
539 ASSERT_TRUE(info
!= NULL
);
540 EXPECT_EQ(kUniform2Size
, info
->size
);
541 EXPECT_EQ(kUniform2Type
, info
->type
);
542 EXPECT_EQ(kUniform2RealLocation
, info
->element_locations
[0]);
543 EXPECT_STREQ(kUniform2Name
, info
->name
.c_str());
544 info
= program
->GetUniformInfo(2);
545 // We emulate certain OpenGL drivers by supplying the name without
546 // the array spec. Our implementation should correctly add the required spec.
547 ASSERT_TRUE(info
!= NULL
);
548 EXPECT_EQ(kUniform3Size
, info
->size
);
549 EXPECT_EQ(kUniform3Type
, info
->type
);
550 EXPECT_EQ(kUniform3RealLocation
, info
->element_locations
[0]);
551 EXPECT_STREQ(kUniform3GoodName
, info
->name
.c_str());
552 EXPECT_TRUE(program
->GetUniformInfo(kInvalidIndex
) == NULL
);
555 TEST_F(ProgramManagerWithShaderTest
, AttachDetachShader
) {
556 static const GLuint kClientProgramId
= 124;
557 static const GLuint kServiceProgramId
= 457;
558 Program
* program
= manager_
.CreateProgram(
559 kClientProgramId
, kServiceProgramId
);
560 ASSERT_TRUE(program
!= NULL
);
561 EXPECT_FALSE(program
->CanLink());
562 const GLuint kVShaderClientId
= 2001;
563 const GLuint kFShaderClientId
= 2002;
564 const GLuint kVShaderServiceId
= 3001;
565 const GLuint kFShaderServiceId
= 3002;
566 Shader
* vshader
= shader_manager_
.CreateShader(
567 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
568 ASSERT_TRUE(vshader
!= NULL
);
569 vshader
->SetStatus(true, "", NULL
);
570 Shader
* fshader
= shader_manager_
.CreateShader(
571 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
572 ASSERT_TRUE(fshader
!= NULL
);
573 fshader
->SetStatus(true, "", NULL
);
574 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
575 EXPECT_FALSE(program
->CanLink());
576 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
577 EXPECT_TRUE(program
->CanLink());
578 program
->DetachShader(&shader_manager_
, vshader
);
579 EXPECT_FALSE(program
->CanLink());
580 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
581 EXPECT_TRUE(program
->CanLink());
582 program
->DetachShader(&shader_manager_
, fshader
);
583 EXPECT_FALSE(program
->CanLink());
584 EXPECT_FALSE(program
->AttachShader(&shader_manager_
, vshader
));
585 EXPECT_FALSE(program
->CanLink());
586 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
587 EXPECT_TRUE(program
->CanLink());
588 vshader
->SetStatus(false, "", NULL
);
589 EXPECT_FALSE(program
->CanLink());
590 vshader
->SetStatus(true, "", NULL
);
591 EXPECT_TRUE(program
->CanLink());
592 fshader
->SetStatus(false, "", NULL
);
593 EXPECT_FALSE(program
->CanLink());
594 fshader
->SetStatus(true, "", NULL
);
595 EXPECT_TRUE(program
->CanLink());
596 EXPECT_TRUE(program
->DetachShader(&shader_manager_
, fshader
));
597 EXPECT_FALSE(program
->DetachShader(&shader_manager_
, fshader
));
600 TEST_F(ProgramManagerWithShaderTest
, GetUniformFakeLocation
) {
601 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
602 ASSERT_TRUE(program
!= NULL
);
603 // Emulate the situation that uniform3[1] isn't used and optimized out by
604 // a driver, so it's location is -1.
605 Program::UniformInfo
* uniform
= const_cast<Program::UniformInfo
*>(
606 program
->GetUniformInfo(2));
607 ASSERT_TRUE(uniform
!= NULL
&& kUniform3Size
== 2);
608 EXPECT_EQ(kUniform3Size
, uniform
->size
);
609 uniform
->element_locations
[1] = -1;
610 EXPECT_EQ(kUniform1FakeLocation
,
611 program
->GetUniformFakeLocation(kUniform1Name
));
612 EXPECT_EQ(kUniform2FakeLocation
,
613 program
->GetUniformFakeLocation(kUniform2Name
));
614 EXPECT_EQ(kUniform3FakeLocation
,
615 program
->GetUniformFakeLocation(kUniform3BadName
));
616 // Check we can get uniform2 as "uniform2" even though the name is
618 EXPECT_EQ(kUniform2FakeLocation
,
619 program
->GetUniformFakeLocation("uniform2"));
620 // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
621 // returning "uniform3"
622 EXPECT_EQ(kUniform3FakeLocation
,
623 program
->GetUniformFakeLocation(kUniform3GoodName
));
624 // Check that we can get the locations of the array elements > 1
625 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation
, 1),
626 program
->GetUniformFakeLocation("uniform2[1]"));
627 EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation
, 2),
628 program
->GetUniformFakeLocation("uniform2[2]"));
629 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform2[3]"));
630 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform3[1]"));
631 EXPECT_EQ(-1, program
->GetUniformFakeLocation("uniform3[2]"));
634 TEST_F(ProgramManagerWithShaderTest
, GetUniformInfoByFakeLocation
) {
635 const GLint kInvalidLocation
= 1234;
636 const Program::UniformInfo
* info
;
637 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
638 GLint real_location
= -1;
639 GLint array_index
= -1;
640 ASSERT_TRUE(program
!= NULL
);
641 info
= program
->GetUniformInfoByFakeLocation(
642 kUniform2FakeLocation
, &real_location
, &array_index
);
643 EXPECT_EQ(kUniform2RealLocation
, real_location
);
644 EXPECT_EQ(0, array_index
);
645 ASSERT_TRUE(info
!= NULL
);
646 EXPECT_EQ(kUniform2Type
, info
->type
);
649 info
= program
->GetUniformInfoByFakeLocation(
650 kInvalidLocation
, &real_location
, &array_index
);
651 EXPECT_TRUE(info
== NULL
);
652 EXPECT_EQ(-1, real_location
);
653 EXPECT_EQ(-1, array_index
);
654 GLint loc
= program
->GetUniformFakeLocation("uniform2[2]");
655 info
= program
->GetUniformInfoByFakeLocation(
656 loc
, &real_location
, &array_index
);
657 ASSERT_TRUE(info
!= NULL
);
658 EXPECT_EQ(kUniform2RealLocation
+ 2 * 2, real_location
);
659 EXPECT_EQ(2, array_index
);
662 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
663 // that start with "gl_". Our implementation catches these and does not allow
664 // them back to client.
665 TEST_F(ProgramManagerWithShaderTest
, GLDriverReturnsGLUnderscoreUniform
) {
666 static const char* kUniform2Name
= "gl_longNameWeCanCheckFor";
667 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
671 kUniform1FakeLocation
,
672 kUniform1RealLocation
,
673 kUniform1DesiredLocation
,
679 kUniform2FakeLocation
,
680 kUniform2RealLocation
,
681 kUniform2DesiredLocation
,
687 kUniform3FakeLocation
,
688 kUniform3RealLocation
,
689 kUniform3DesiredLocation
,
693 const size_t kNumUniforms
= arraysize(kUniforms
);
694 static const GLuint kClientProgramId
= 1234;
695 static const GLuint kServiceProgramId
= 5679;
696 const GLuint kVShaderClientId
= 2001;
697 const GLuint kFShaderClientId
= 2002;
698 const GLuint kVShaderServiceId
= 3001;
699 const GLuint kFShaderServiceId
= 3002;
701 kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
, kServiceProgramId
);
702 Shader
* vshader
= shader_manager_
.CreateShader(
703 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
704 ASSERT_TRUE(vshader
!= NULL
);
705 vshader
->SetStatus(true, "", NULL
);
706 Shader
* fshader
= shader_manager_
.CreateShader(
707 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
708 ASSERT_TRUE(fshader
!= NULL
);
709 fshader
->SetStatus(true, "", NULL
);
711 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
712 ASSERT_TRUE(program
!= NULL
);
713 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
714 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
715 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
716 base::Bind(&ShaderCacheCb
));
718 program
->GetProgramiv(GL_ACTIVE_ATTRIBUTES
, &value
);
720 // Check that we skipped the "gl_" uniform.
721 program
->GetProgramiv(GL_ACTIVE_UNIFORMS
, &value
);
723 // Check that our max length adds room for the array spec and is not as long
724 // as the "gl_" uniform we skipped.
725 // +4u is to account for "gl_" and NULL terminator.
726 program
->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH
, &value
);
727 EXPECT_EQ(strlen(kUniform3BadName
) + 4u, static_cast<size_t>(value
));
730 // Test the bug comparing similar array names is fixed.
731 TEST_F(ProgramManagerWithShaderTest
, SimilarArrayNames
) {
732 static const char* kUniform2Name
= "u_nameLong[0]";
733 static const char* kUniform3Name
= "u_name[0]";
734 static const GLint kUniform2Size
= 2;
735 static const GLint kUniform3Size
= 2;
736 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
740 kUniform1FakeLocation
,
741 kUniform1RealLocation
,
742 kUniform1DesiredLocation
,
748 kUniform2FakeLocation
,
749 kUniform2RealLocation
,
750 kUniform2DesiredLocation
,
756 kUniform3FakeLocation
,
757 kUniform3RealLocation
,
758 kUniform3DesiredLocation
,
762 const size_t kNumUniforms
= arraysize(kUniforms
);
763 static const GLuint kClientProgramId
= 1234;
764 static const GLuint kServiceProgramId
= 5679;
765 const GLuint kVShaderClientId
= 2001;
766 const GLuint kFShaderClientId
= 2002;
767 const GLuint kVShaderServiceId
= 3001;
768 const GLuint kFShaderServiceId
= 3002;
770 kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
, kServiceProgramId
);
771 Shader
* vshader
= shader_manager_
.CreateShader(
772 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
773 ASSERT_TRUE(vshader
!= NULL
);
774 vshader
->SetStatus(true, "", NULL
);
775 Shader
* fshader
= shader_manager_
.CreateShader(
776 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
777 ASSERT_TRUE(fshader
!= NULL
);
778 fshader
->SetStatus(true, "", NULL
);
780 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
781 ASSERT_TRUE(program
!= NULL
);
782 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
783 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
784 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
785 base::Bind(&ShaderCacheCb
));
787 // Check that we get the correct locations.
788 EXPECT_EQ(kUniform2FakeLocation
,
789 program
->GetUniformFakeLocation(kUniform2Name
));
790 EXPECT_EQ(kUniform3FakeLocation
,
791 program
->GetUniformFakeLocation(kUniform3Name
));
794 // Some GL drivers incorrectly return the wrong type. For example they return
795 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
796 TEST_F(ProgramManagerWithShaderTest
, GLDriverReturnsWrongTypeInfo
) {
797 static GLenum kAttrib2BadType
= GL_FLOAT_VEC2
;
798 static GLenum kAttrib2GoodType
= GL_FLOAT_MAT2
;
799 static GLenum kUniform2BadType
= GL_FLOAT_VEC3
;
800 static GLenum kUniform2GoodType
= GL_FLOAT_MAT3
;
801 MockShaderTranslator shader_translator
;
802 ShaderTranslator::VariableMap attrib_map
;
803 ShaderTranslator::VariableMap uniform_map
;
804 ShaderTranslator::VariableMap varying_map
;
805 attrib_map
[kAttrib1Name
] = ShaderTranslatorInterface::VariableInfo(
806 kAttrib1Type
, kAttrib1Size
, kAttrib1Precision
,
807 kAttribStaticUse
, kAttrib1Name
);
808 attrib_map
[kAttrib2Name
] = ShaderTranslatorInterface::VariableInfo(
809 kAttrib2GoodType
, kAttrib2Size
, kAttrib2Precision
,
810 kAttribStaticUse
, kAttrib2Name
);
811 attrib_map
[kAttrib3Name
] = ShaderTranslatorInterface::VariableInfo(
812 kAttrib3Type
, kAttrib3Size
, kAttrib3Precision
,
813 kAttribStaticUse
, kAttrib3Name
);
814 uniform_map
[kUniform1Name
] = ShaderTranslatorInterface::VariableInfo(
815 kUniform1Type
, kUniform1Size
, kUniform1Precision
,
816 kUniform1StaticUse
, kUniform1Name
);
817 uniform_map
[kUniform2Name
] = ShaderTranslatorInterface::VariableInfo(
818 kUniform2GoodType
, kUniform2Size
, kUniform2Precision
,
819 kUniform2StaticUse
, kUniform2Name
);
820 uniform_map
[kUniform3GoodName
] = ShaderTranslatorInterface::VariableInfo(
821 kUniform3Type
, kUniform3Size
, kUniform3Precision
,
822 kUniform3StaticUse
, kUniform3GoodName
);
823 EXPECT_CALL(shader_translator
, attrib_map())
824 .WillRepeatedly(ReturnRef(attrib_map
));
825 EXPECT_CALL(shader_translator
, uniform_map())
826 .WillRepeatedly(ReturnRef(uniform_map
));
827 EXPECT_CALL(shader_translator
, varying_map())
828 .WillRepeatedly(ReturnRef(varying_map
));
829 ShaderTranslator::NameMap name_map
;
830 EXPECT_CALL(shader_translator
, name_map())
831 .WillRepeatedly(ReturnRef(name_map
));
832 const GLuint kVShaderClientId
= 2001;
833 const GLuint kFShaderClientId
= 2002;
834 const GLuint kVShaderServiceId
= 3001;
835 const GLuint kFShaderServiceId
= 3002;
836 Shader
* vshader
= shader_manager_
.CreateShader(
837 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
838 ASSERT_TRUE(vshader
!= NULL
);
839 vshader
->SetStatus(true, "", &shader_translator
);
840 Shader
* fshader
= shader_manager_
.CreateShader(
841 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
842 ASSERT_TRUE(fshader
!= NULL
);
843 fshader
->SetStatus(true, "", &shader_translator
);
844 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
845 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
846 { kAttrib2Name
, kAttrib2Size
, kAttrib2BadType
, kAttrib2Location
, },
847 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
849 static ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
853 kUniform1FakeLocation
,
854 kUniform1RealLocation
,
855 kUniform1DesiredLocation
,
861 kUniform2FakeLocation
,
862 kUniform2RealLocation
,
863 kUniform2DesiredLocation
,
869 kUniform3FakeLocation
,
870 kUniform3RealLocation
,
871 kUniform3DesiredLocation
,
875 const size_t kNumAttribs
= arraysize(kAttribs
);
876 const size_t kNumUniforms
= arraysize(kUniforms
);
877 static const GLuint kClientProgramId
= 1234;
878 static const GLuint kServiceProgramId
= 5679;
879 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
881 Program
* program
= manager_
.CreateProgram(
882 kClientProgramId
, kServiceProgramId
);
883 ASSERT_TRUE(program
!= NULL
);
884 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
885 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
886 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
887 base::Bind(&ShaderCacheCb
));
888 // Check that we got the good type, not the bad.
890 for (unsigned index
= 0; index
< kNumAttribs
; ++index
) {
891 const Program::VertexAttrib
* attrib_info
=
892 program
->GetAttribInfo(index
);
893 ASSERT_TRUE(attrib_info
!= NULL
);
894 ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.find(
896 ASSERT_TRUE(it
!= attrib_map
.end());
897 EXPECT_EQ(it
->first
, attrib_info
->name
);
898 EXPECT_EQ(static_cast<GLenum
>(it
->second
.type
), attrib_info
->type
);
899 EXPECT_EQ(it
->second
.size
, attrib_info
->size
);
900 EXPECT_EQ(it
->second
.name
, attrib_info
->name
);
903 for (unsigned index
= 0; index
< kNumUniforms
; ++index
) {
904 const Program::UniformInfo
* uniform_info
=
905 program
->GetUniformInfo(index
);
906 ASSERT_TRUE(uniform_info
!= NULL
);
907 ShaderTranslator::VariableMap::const_iterator it
= uniform_map
.find(
909 ASSERT_TRUE(it
!= uniform_map
.end());
910 EXPECT_EQ(it
->first
, uniform_info
->name
);
911 EXPECT_EQ(static_cast<GLenum
>(it
->second
.type
), uniform_info
->type
);
912 EXPECT_EQ(it
->second
.size
, uniform_info
->size
);
913 EXPECT_EQ(it
->second
.name
, uniform_info
->name
);
917 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoUseCount
) {
918 static const GLuint kClientProgramId
= 124;
919 static const GLuint kServiceProgramId
= 457;
920 Program
* program
= manager_
.CreateProgram(
921 kClientProgramId
, kServiceProgramId
);
922 ASSERT_TRUE(program
!= NULL
);
923 EXPECT_FALSE(program
->CanLink());
924 const GLuint kVShaderClientId
= 2001;
925 const GLuint kFShaderClientId
= 2002;
926 const GLuint kVShaderServiceId
= 3001;
927 const GLuint kFShaderServiceId
= 3002;
928 Shader
* vshader
= shader_manager_
.CreateShader(
929 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
930 ASSERT_TRUE(vshader
!= NULL
);
931 vshader
->SetStatus(true, "", NULL
);
932 Shader
* fshader
= shader_manager_
.CreateShader(
933 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
934 ASSERT_TRUE(fshader
!= NULL
);
935 fshader
->SetStatus(true, "", NULL
);
936 EXPECT_FALSE(vshader
->InUse());
937 EXPECT_FALSE(fshader
->InUse());
938 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
939 EXPECT_TRUE(vshader
->InUse());
940 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
941 EXPECT_TRUE(fshader
->InUse());
942 EXPECT_TRUE(program
->CanLink());
943 EXPECT_FALSE(program
->InUse());
944 EXPECT_FALSE(program
->IsDeleted());
945 manager_
.UseProgram(program
);
946 EXPECT_TRUE(program
->InUse());
947 manager_
.UseProgram(program
);
948 EXPECT_TRUE(program
->InUse());
949 manager_
.MarkAsDeleted(&shader_manager_
, program
);
950 EXPECT_TRUE(program
->IsDeleted());
951 Program
* info2
= manager_
.GetProgram(kClientProgramId
);
952 EXPECT_EQ(program
, info2
);
953 manager_
.UnuseProgram(&shader_manager_
, program
);
954 EXPECT_TRUE(program
->InUse());
955 // this should delete the info.
956 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
958 .RetiresOnSaturation();
959 manager_
.UnuseProgram(&shader_manager_
, program
);
960 info2
= manager_
.GetProgram(kClientProgramId
);
961 EXPECT_TRUE(info2
== NULL
);
962 EXPECT_FALSE(vshader
->InUse());
963 EXPECT_FALSE(fshader
->InUse());
966 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoUseCount2
) {
967 static const GLuint kClientProgramId
= 124;
968 static const GLuint kServiceProgramId
= 457;
969 Program
* program
= manager_
.CreateProgram(
970 kClientProgramId
, kServiceProgramId
);
971 ASSERT_TRUE(program
!= NULL
);
972 EXPECT_FALSE(program
->CanLink());
973 const GLuint kVShaderClientId
= 2001;
974 const GLuint kFShaderClientId
= 2002;
975 const GLuint kVShaderServiceId
= 3001;
976 const GLuint kFShaderServiceId
= 3002;
977 Shader
* vshader
= shader_manager_
.CreateShader(
978 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
979 ASSERT_TRUE(vshader
!= NULL
);
980 vshader
->SetStatus(true, "", NULL
);
981 Shader
* fshader
= shader_manager_
.CreateShader(
982 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
983 ASSERT_TRUE(fshader
!= NULL
);
984 fshader
->SetStatus(true, "", NULL
);
985 EXPECT_FALSE(vshader
->InUse());
986 EXPECT_FALSE(fshader
->InUse());
987 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
988 EXPECT_TRUE(vshader
->InUse());
989 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
990 EXPECT_TRUE(fshader
->InUse());
991 EXPECT_TRUE(program
->CanLink());
992 EXPECT_FALSE(program
->InUse());
993 EXPECT_FALSE(program
->IsDeleted());
994 manager_
.UseProgram(program
);
995 EXPECT_TRUE(program
->InUse());
996 manager_
.UseProgram(program
);
997 EXPECT_TRUE(program
->InUse());
998 manager_
.UnuseProgram(&shader_manager_
, program
);
999 EXPECT_TRUE(program
->InUse());
1000 manager_
.UnuseProgram(&shader_manager_
, program
);
1001 EXPECT_FALSE(program
->InUse());
1002 Program
* info2
= manager_
.GetProgram(kClientProgramId
);
1003 EXPECT_EQ(program
, info2
);
1004 // this should delete the program.
1005 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
1007 .RetiresOnSaturation();
1008 manager_
.MarkAsDeleted(&shader_manager_
, program
);
1009 info2
= manager_
.GetProgram(kClientProgramId
);
1010 EXPECT_TRUE(info2
== NULL
);
1011 EXPECT_FALSE(vshader
->InUse());
1012 EXPECT_FALSE(fshader
->InUse());
1015 TEST_F(ProgramManagerWithShaderTest
, ProgramInfoGetProgramInfo
) {
1016 CommonDecoder::Bucket bucket
;
1017 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1018 ASSERT_TRUE(program
!= NULL
);
1019 program
->GetProgramInfo(&manager_
, &bucket
);
1020 ProgramInfoHeader
* header
=
1021 bucket
.GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
1022 ASSERT_TRUE(header
!= NULL
);
1023 EXPECT_EQ(1u, header
->link_status
);
1024 EXPECT_EQ(arraysize(kAttribs
), header
->num_attribs
);
1025 EXPECT_EQ(arraysize(kUniforms
), header
->num_uniforms
);
1026 const ProgramInput
* inputs
= bucket
.GetDataAs
<const ProgramInput
*>(
1028 sizeof(ProgramInput
) * (header
->num_attribs
+ header
->num_uniforms
));
1029 ASSERT_TRUE(inputs
!= NULL
);
1030 const ProgramInput
* input
= inputs
;
1031 // TODO(gman): Don't assume these are in order.
1032 for (uint32 ii
= 0; ii
< header
->num_attribs
; ++ii
) {
1033 const AttribInfo
& expected
= kAttribs
[ii
];
1034 EXPECT_EQ(expected
.size
, input
->size
);
1035 EXPECT_EQ(expected
.type
, input
->type
);
1036 const int32
* location
= bucket
.GetDataAs
<const int32
*>(
1037 input
->location_offset
, sizeof(int32
));
1038 ASSERT_TRUE(location
!= NULL
);
1039 EXPECT_EQ(expected
.location
, *location
);
1040 const char* name_buf
= bucket
.GetDataAs
<const char*>(
1041 input
->name_offset
, input
->name_length
);
1042 ASSERT_TRUE(name_buf
!= NULL
);
1043 std::string
name(name_buf
, input
->name_length
);
1044 EXPECT_STREQ(expected
.name
, name
.c_str());
1047 // TODO(gman): Don't assume these are in order.
1048 for (uint32 ii
= 0; ii
< header
->num_uniforms
; ++ii
) {
1049 const UniformInfo
& expected
= kUniforms
[ii
];
1050 EXPECT_EQ(expected
.size
, input
->size
);
1051 EXPECT_EQ(expected
.type
, input
->type
);
1052 const int32
* locations
= bucket
.GetDataAs
<const int32
*>(
1053 input
->location_offset
, sizeof(int32
) * input
->size
);
1054 ASSERT_TRUE(locations
!= NULL
);
1055 for (int32 jj
= 0; jj
< input
->size
; ++jj
) {
1057 ProgramManager::MakeFakeLocation(expected
.fake_location
, jj
),
1060 const char* name_buf
= bucket
.GetDataAs
<const char*>(
1061 input
->name_offset
, input
->name_length
);
1062 ASSERT_TRUE(name_buf
!= NULL
);
1063 std::string
name(name_buf
, input
->name_length
);
1064 EXPECT_STREQ(expected
.good_name
, name
.c_str());
1067 EXPECT_EQ(header
->num_attribs
+ header
->num_uniforms
,
1068 static_cast<uint32
>(input
- inputs
));
1071 // Some drivers optimize out unused uniform array elements, so their
1072 // location would be -1.
1073 TEST_F(ProgramManagerWithShaderTest
, UnusedUniformArrayElements
) {
1074 CommonDecoder::Bucket bucket
;
1075 const Program
* program
= manager_
.GetProgram(kClientProgramId
);
1076 ASSERT_TRUE(program
!= NULL
);
1077 // Emulate the situation that only the first element has a valid location.
1078 // TODO(zmo): Don't assume these are in order.
1079 for (size_t ii
= 0; ii
< arraysize(kUniforms
); ++ii
) {
1080 Program::UniformInfo
* uniform
= const_cast<Program::UniformInfo
*>(
1081 program
->GetUniformInfo(ii
));
1082 ASSERT_TRUE(uniform
!= NULL
);
1083 EXPECT_EQ(static_cast<size_t>(kUniforms
[ii
].size
),
1084 uniform
->element_locations
.size());
1085 for (GLsizei jj
= 1; jj
< uniform
->size
; ++jj
)
1086 uniform
->element_locations
[jj
] = -1;
1088 program
->GetProgramInfo(&manager_
, &bucket
);
1089 ProgramInfoHeader
* header
=
1090 bucket
.GetDataAs
<ProgramInfoHeader
*>(0, sizeof(ProgramInfoHeader
));
1091 ASSERT_TRUE(header
!= NULL
);
1092 EXPECT_EQ(1u, header
->link_status
);
1093 EXPECT_EQ(arraysize(kAttribs
), header
->num_attribs
);
1094 EXPECT_EQ(arraysize(kUniforms
), header
->num_uniforms
);
1095 const ProgramInput
* inputs
= bucket
.GetDataAs
<const ProgramInput
*>(
1097 sizeof(ProgramInput
) * (header
->num_attribs
+ header
->num_uniforms
));
1098 ASSERT_TRUE(inputs
!= NULL
);
1099 const ProgramInput
* input
= inputs
+ header
->num_attribs
;
1100 for (uint32 ii
= 0; ii
< header
->num_uniforms
; ++ii
) {
1101 const UniformInfo
& expected
= kUniforms
[ii
];
1102 EXPECT_EQ(expected
.size
, input
->size
);
1103 const int32
* locations
= bucket
.GetDataAs
<const int32
*>(
1104 input
->location_offset
, sizeof(int32
) * input
->size
);
1105 ASSERT_TRUE(locations
!= NULL
);
1107 ProgramManager::MakeFakeLocation(expected
.fake_location
, 0),
1109 for (int32 jj
= 1; jj
< input
->size
; ++jj
)
1110 EXPECT_EQ(-1, locations
[jj
]);
1115 TEST_F(ProgramManagerWithShaderTest
, BindAttribLocationConflicts
) {
1117 const GLuint kVShaderClientId
= 1;
1118 const GLuint kVShaderServiceId
= 11;
1119 const GLuint kFShaderClientId
= 2;
1120 const GLuint kFShaderServiceId
= 12;
1121 MockShaderTranslator shader_translator
;
1122 ShaderTranslator::VariableMap attrib_map
;
1123 for (uint32 ii
= 0; ii
< kNumAttribs
; ++ii
) {
1124 attrib_map
[kAttribs
[ii
].name
] = ShaderTranslatorInterface::VariableInfo(
1127 SH_PRECISION_MEDIUMP
,
1131 ShaderTranslator::VariableMap uniform_map
;
1132 ShaderTranslator::VariableMap varying_map
;
1133 EXPECT_CALL(shader_translator
, attrib_map())
1134 .WillRepeatedly(ReturnRef(attrib_map
));
1135 EXPECT_CALL(shader_translator
, uniform_map())
1136 .WillRepeatedly(ReturnRef(uniform_map
));
1137 EXPECT_CALL(shader_translator
, varying_map())
1138 .WillRepeatedly(ReturnRef(varying_map
));
1139 ShaderTranslator::NameMap name_map
;
1140 EXPECT_CALL(shader_translator
, name_map())
1141 .WillRepeatedly(ReturnRef(name_map
));
1142 // Check we can create shader.
1143 Shader
* vshader
= shader_manager_
.CreateShader(
1144 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1145 Shader
* fshader
= shader_manager_
.CreateShader(
1146 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1147 // Check shader got created.
1148 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1150 vshader
->SetStatus(true, "", &shader_translator
);
1151 // Check attrib infos got copied.
1152 for (ShaderTranslator::VariableMap::const_iterator it
= attrib_map
.begin();
1153 it
!= attrib_map
.end(); ++it
) {
1154 const Shader::VariableInfo
* variable_info
=
1155 vshader
->GetAttribInfo(it
->first
);
1156 ASSERT_TRUE(variable_info
!= NULL
);
1157 EXPECT_EQ(it
->second
.type
, variable_info
->type
);
1158 EXPECT_EQ(it
->second
.size
, variable_info
->size
);
1159 EXPECT_EQ(it
->second
.precision
, variable_info
->precision
);
1160 EXPECT_EQ(it
->second
.static_use
, variable_info
->static_use
);
1161 EXPECT_EQ(it
->second
.name
, variable_info
->name
);
1163 fshader
->SetStatus(true, "", NULL
);
1166 const GLuint kClientProgramId
= 6666;
1167 const GLuint kServiceProgramId
= 8888;
1169 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1170 ASSERT_TRUE(program
!= NULL
);
1171 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1172 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1174 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1175 EXPECT_TRUE(LinkAsExpected(program
, true));
1177 program
->SetAttribLocationBinding(kAttrib1Name
, 0);
1178 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1179 EXPECT_TRUE(LinkAsExpected(program
, true));
1181 program
->SetAttribLocationBinding("xxx", 0);
1182 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1183 EXPECT_TRUE(LinkAsExpected(program
, true));
1185 program
->SetAttribLocationBinding(kAttrib2Name
, 1);
1186 EXPECT_FALSE(program
->DetectAttribLocationBindingConflicts());
1187 EXPECT_TRUE(LinkAsExpected(program
, true));
1189 program
->SetAttribLocationBinding(kAttrib2Name
, 0);
1190 EXPECT_TRUE(program
->DetectAttribLocationBindingConflicts());
1191 EXPECT_TRUE(LinkAsExpected(program
, false));
1194 TEST_F(ProgramManagerWithShaderTest
, UniformsPrecisionMismatch
) {
1196 const GLuint kVShaderClientId
= 1;
1197 const GLuint kVShaderServiceId
= 11;
1198 const GLuint kFShaderClientId
= 2;
1199 const GLuint kFShaderServiceId
= 12;
1201 MockShaderTranslator vertex_shader_translator
;
1202 ShaderTranslator::VariableMap vertex_attrib_map
;
1203 ShaderTranslator::VariableMap vertex_uniform_map
;
1204 vertex_uniform_map
["a"] = ShaderTranslator::VariableInfo(
1205 1, 3, SH_PRECISION_MEDIUMP
, 1, "a");
1206 ShaderTranslator::VariableMap vertex_varying_map
;
1207 ShaderTranslator::NameMap vertex_name_map
;
1208 EXPECT_CALL(vertex_shader_translator
, attrib_map())
1209 .WillRepeatedly(ReturnRef(vertex_attrib_map
));
1210 EXPECT_CALL(vertex_shader_translator
, uniform_map())
1211 .WillRepeatedly(ReturnRef(vertex_uniform_map
));
1212 EXPECT_CALL(vertex_shader_translator
, varying_map())
1213 .WillRepeatedly(ReturnRef(vertex_varying_map
));
1214 EXPECT_CALL(vertex_shader_translator
, name_map())
1215 .WillRepeatedly(ReturnRef(vertex_name_map
));
1217 MockShaderTranslator frag_shader_translator
;
1218 ShaderTranslator::VariableMap frag_attrib_map
;
1219 ShaderTranslator::VariableMap frag_uniform_map
;
1220 frag_uniform_map
["a"] = ShaderTranslator::VariableInfo(
1221 1, 3, SH_PRECISION_LOWP
, 1, "a");
1222 ShaderTranslator::VariableMap frag_varying_map
;
1223 ShaderTranslator::NameMap frag_name_map
;
1224 EXPECT_CALL(frag_shader_translator
, attrib_map())
1225 .WillRepeatedly(ReturnRef(frag_attrib_map
));
1226 EXPECT_CALL(frag_shader_translator
, uniform_map())
1227 .WillRepeatedly(ReturnRef(frag_uniform_map
));
1228 EXPECT_CALL(frag_shader_translator
, varying_map())
1229 .WillRepeatedly(ReturnRef(frag_varying_map
));
1230 EXPECT_CALL(frag_shader_translator
, name_map())
1231 .WillRepeatedly(ReturnRef(frag_name_map
));
1233 // Check we can create shader.
1234 Shader
* vshader
= shader_manager_
.CreateShader(
1235 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1236 Shader
* fshader
= shader_manager_
.CreateShader(
1237 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1238 // Check shader got created.
1239 ASSERT_TRUE(vshader
!= NULL
&& fshader
!= NULL
);
1241 vshader
->SetStatus(true, "", &vertex_shader_translator
);
1242 fshader
->SetStatus(true, "", &frag_shader_translator
);
1245 const GLuint kClientProgramId
= 6666;
1246 const GLuint kServiceProgramId
= 8888;
1248 manager_
.CreateProgram(kClientProgramId
, kServiceProgramId
);
1249 ASSERT_TRUE(program
!= NULL
);
1250 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1251 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1253 std::string conflicting_name
;
1255 EXPECT_TRUE(program
->DetectUniformsMismatch(&conflicting_name
));
1256 EXPECT_EQ("a", conflicting_name
);
1257 EXPECT_TRUE(LinkAsExpected(program
, false));
1260 // If a varying has different type in the vertex and fragment
1261 // shader, linking should fail.
1262 TEST_F(ProgramManagerWithShaderTest
, VaryingTypeMismatch
) {
1263 const VarInfo kVertexVarying
=
1264 { SH_FLOAT_VEC3
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1265 const VarInfo kFragmentVarying
=
1266 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1267 Program
* program
= SetupShaderVariableTest(
1268 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1270 std::string conflicting_name
;
1272 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1273 EXPECT_EQ("a", conflicting_name
);
1274 EXPECT_TRUE(LinkAsExpected(program
, false));
1277 // If a varying has different array size in the vertex and fragment
1278 // shader, linking should fail.
1279 TEST_F(ProgramManagerWithShaderTest
, VaryingArraySizeMismatch
) {
1280 const VarInfo kVertexVarying
=
1281 { SH_FLOAT
, 2, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1282 const VarInfo kFragmentVarying
=
1283 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1284 Program
* program
= SetupShaderVariableTest(
1285 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1287 std::string conflicting_name
;
1289 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1290 EXPECT_EQ("a", conflicting_name
);
1291 EXPECT_TRUE(LinkAsExpected(program
, false));
1294 // If a varying has different precision in the vertex and fragment
1295 // shader, linking should succeed.
1296 TEST_F(ProgramManagerWithShaderTest
, VaryingPrecisionMismatch
) {
1297 const VarInfo kVertexVarying
=
1298 { SH_FLOAT
, 2, SH_PRECISION_HIGHP
, 1, "a", kVarVarying
};
1299 const VarInfo kFragmentVarying
=
1300 { SH_FLOAT
, 2, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1301 Program
* program
= SetupShaderVariableTest(
1302 &kVertexVarying
, 1, &kFragmentVarying
, 1);
1304 std::string conflicting_name
;
1306 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1307 EXPECT_TRUE(conflicting_name
.empty());
1308 EXPECT_TRUE(LinkAsExpected(program
, true));
1311 // If a varying is statically used in fragment shader but not
1312 // declared in vertex shader, link should fail.
1313 TEST_F(ProgramManagerWithShaderTest
, VaryingMissing
) {
1314 const VarInfo kFragmentVarying
=
1315 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
};
1316 Program
* program
= SetupShaderVariableTest(
1317 NULL
, 0, &kFragmentVarying
, 1);
1319 std::string conflicting_name
;
1321 EXPECT_TRUE(program
->DetectVaryingsMismatch(&conflicting_name
));
1322 EXPECT_EQ("a", conflicting_name
);
1323 EXPECT_TRUE(LinkAsExpected(program
, false));
1326 // If a varying is declared but not statically used in fragment
1327 // shader, even if it's not declared in vertex shader, link should
1329 TEST_F(ProgramManagerWithShaderTest
, InactiveVarying
) {
1330 const VarInfo kFragmentVarying
=
1331 { SH_FLOAT
, 3, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
};
1332 Program
* program
= SetupShaderVariableTest(
1333 NULL
, 0, &kFragmentVarying
, 1);
1335 std::string conflicting_name
;
1337 EXPECT_FALSE(program
->DetectVaryingsMismatch(&conflicting_name
));
1338 EXPECT_TRUE(conflicting_name
.empty());
1339 EXPECT_TRUE(LinkAsExpected(program
, true));
1342 // Uniforms and attributes are both global variables, thus sharing
1343 // the same namespace. Any name conflicts should cause link
1345 TEST_F(ProgramManagerWithShaderTest
, AttribUniformNameConflict
) {
1346 const VarInfo kVertexAttribute
=
1347 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarAttribute
};
1348 const VarInfo kFragmentUniform
=
1349 { SH_FLOAT_VEC4
, 1, SH_PRECISION_MEDIUMP
, 1, "a", kVarUniform
};
1350 Program
* program
= SetupShaderVariableTest(
1351 &kVertexAttribute
, 1, &kFragmentUniform
, 1);
1353 std::string conflicting_name
;
1355 EXPECT_TRUE(program
->DetectGlobalNameConflicts(&conflicting_name
));
1356 EXPECT_EQ("a", conflicting_name
);
1357 EXPECT_TRUE(LinkAsExpected(program
, false));
1360 // Varyings go over 8 rows.
1361 TEST_F(ProgramManagerWithShaderTest
, TooManyVaryings
) {
1362 const VarInfo kVertexVaryings
[] = {
1363 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1364 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1366 const VarInfo kFragmentVaryings
[] = {
1367 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1368 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1370 Program
* program
= SetupShaderVariableTest(
1371 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1374 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1375 EXPECT_TRUE(LinkAsExpected(program
, false));
1378 // Varyings go over 8 rows but some are inactive
1379 TEST_F(ProgramManagerWithShaderTest
, TooManyInactiveVaryings
) {
1380 const VarInfo kVertexVaryings
[] = {
1381 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1382 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1384 const VarInfo kFragmentVaryings
[] = {
1385 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
},
1386 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1388 Program
* program
= SetupShaderVariableTest(
1389 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1392 program
->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed
));
1393 EXPECT_TRUE(LinkAsExpected(program
, true));
1396 // Varyings go over 8 rows but some are inactive.
1397 // However, we still fail the check if kCountAll option is used.
1398 TEST_F(ProgramManagerWithShaderTest
, CountAllVaryingsInPacking
) {
1399 const VarInfo kVertexVaryings
[] = {
1400 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 1, "a", kVarVarying
},
1401 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1403 const VarInfo kFragmentVaryings
[] = {
1404 { SH_FLOAT_VEC4
, 4, SH_PRECISION_MEDIUMP
, 0, "a", kVarVarying
},
1405 { SH_FLOAT_VEC4
, 5, SH_PRECISION_MEDIUMP
, 1, "b", kVarVarying
}
1407 Program
* program
= SetupShaderVariableTest(
1408 kVertexVaryings
, 2, kFragmentVaryings
, 2);
1410 EXPECT_FALSE(program
->CheckVaryingsPacking(Program::kCountAll
));
1413 TEST_F(ProgramManagerWithShaderTest
, ClearWithSamplerTypes
) {
1414 const GLuint kVShaderClientId
= 2001;
1415 const GLuint kFShaderClientId
= 2002;
1416 const GLuint kVShaderServiceId
= 3001;
1417 const GLuint kFShaderServiceId
= 3002;
1418 Shader
* vshader
= shader_manager_
.CreateShader(
1419 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1420 ASSERT_TRUE(vshader
!= NULL
);
1421 vshader
->SetStatus(true, NULL
, NULL
);
1422 Shader
* fshader
= shader_manager_
.CreateShader(
1423 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1424 ASSERT_TRUE(fshader
!= NULL
);
1425 fshader
->SetStatus(true, NULL
, NULL
);
1426 static const GLuint kClientProgramId
= 1234;
1427 static const GLuint kServiceProgramId
= 5679;
1428 Program
* program
= manager_
.CreateProgram(
1429 kClientProgramId
, kServiceProgramId
);
1430 ASSERT_TRUE(program
!= NULL
);
1431 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1432 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1434 static const GLenum kSamplerTypes
[] = {
1437 GL_SAMPLER_EXTERNAL_OES
,
1439 GL_SAMPLER_2D_RECT_ARB
,
1441 const size_t kNumSamplerTypes
= arraysize(kSamplerTypes
);
1442 for (size_t ii
= 0; ii
< kNumSamplerTypes
; ++ii
) {
1443 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1444 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1445 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1446 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1448 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1452 kUniform1FakeLocation
,
1453 kUniform1RealLocation
,
1454 kUniform1DesiredLocation
,
1460 kUniform2FakeLocation
,
1461 kUniform2RealLocation
,
1462 kUniform2DesiredLocation
,
1468 kUniform3FakeLocation
,
1469 kUniform3RealLocation
,
1470 kUniform3DesiredLocation
,
1474 const size_t kNumAttribs
= arraysize(kAttribs
);
1475 const size_t kNumUniforms
= arraysize(kUniforms
);
1476 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1478 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
1479 base::Bind(&ShaderCacheCb
));
1480 SetupExpectationsForClearingUniforms(kUniforms
, kNumUniforms
);
1481 manager_
.ClearUniforms(program
);
1485 TEST_F(ProgramManagerWithShaderTest
, BindUniformLocation
) {
1486 const GLuint kVShaderClientId
= 2001;
1487 const GLuint kFShaderClientId
= 2002;
1488 const GLuint kVShaderServiceId
= 3001;
1489 const GLuint kFShaderServiceId
= 3002;
1491 const GLint kUniform1DesiredLocation
= 10;
1492 const GLint kUniform2DesiredLocation
= -1;
1493 const GLint kUniform3DesiredLocation
= 5;
1495 Shader
* vshader
= shader_manager_
.CreateShader(
1496 kVShaderClientId
, kVShaderServiceId
, GL_VERTEX_SHADER
);
1497 ASSERT_TRUE(vshader
!= NULL
);
1498 vshader
->SetStatus(true, NULL
, NULL
);
1499 Shader
* fshader
= shader_manager_
.CreateShader(
1500 kFShaderClientId
, kFShaderServiceId
, GL_FRAGMENT_SHADER
);
1501 ASSERT_TRUE(fshader
!= NULL
);
1502 fshader
->SetStatus(true, NULL
, NULL
);
1503 static const GLuint kClientProgramId
= 1234;
1504 static const GLuint kServiceProgramId
= 5679;
1505 Program
* program
= manager_
.CreateProgram(
1506 kClientProgramId
, kServiceProgramId
);
1507 ASSERT_TRUE(program
!= NULL
);
1508 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, vshader
));
1509 EXPECT_TRUE(program
->AttachShader(&shader_manager_
, fshader
));
1510 EXPECT_TRUE(program
->SetUniformLocationBinding(
1511 kUniform1Name
, kUniform1DesiredLocation
));
1512 EXPECT_TRUE(program
->SetUniformLocationBinding(
1513 kUniform3BadName
, kUniform3DesiredLocation
));
1515 static ProgramManagerWithShaderTest::AttribInfo kAttribs
[] = {
1516 { kAttrib1Name
, kAttrib1Size
, kAttrib1Type
, kAttrib1Location
, },
1517 { kAttrib2Name
, kAttrib2Size
, kAttrib2Type
, kAttrib2Location
, },
1518 { kAttrib3Name
, kAttrib3Size
, kAttrib3Type
, kAttrib3Location
, },
1520 ProgramManagerWithShaderTest::UniformInfo kUniforms
[] = {
1524 kUniform1FakeLocation
,
1525 kUniform1RealLocation
,
1526 kUniform1DesiredLocation
,
1532 kUniform2FakeLocation
,
1533 kUniform2RealLocation
,
1534 kUniform2DesiredLocation
,
1540 kUniform3FakeLocation
,
1541 kUniform3RealLocation
,
1542 kUniform3DesiredLocation
,
1547 const size_t kNumAttribs
= arraysize(kAttribs
);
1548 const size_t kNumUniforms
= arraysize(kUniforms
);
1549 SetupShader(kAttribs
, kNumAttribs
, kUniforms
, kNumUniforms
,
1551 program
->Link(NULL
, NULL
, NULL
, Program::kCountOnlyStaticallyUsed
,
1552 base::Bind(&ShaderCacheCb
));
1554 EXPECT_EQ(kUniform1DesiredLocation
,
1555 program
->GetUniformFakeLocation(kUniform1Name
));
1556 EXPECT_EQ(kUniform3DesiredLocation
,
1557 program
->GetUniformFakeLocation(kUniform3BadName
));
1558 EXPECT_EQ(kUniform3DesiredLocation
,
1559 program
->GetUniformFakeLocation(kUniform3GoodName
));
1562 class ProgramManagerWithCacheTest
: public GpuServiceTest
{
1564 static const GLuint kClientProgramId
= 1;
1565 static const GLuint kServiceProgramId
= 10;
1566 static const GLuint kVertexShaderClientId
= 2;
1567 static const GLuint kFragmentShaderClientId
= 20;
1568 static const GLuint kVertexShaderServiceId
= 3;
1569 static const GLuint kFragmentShaderServiceId
= 30;
1571 ProgramManagerWithCacheTest()
1572 : cache_(new MockProgramCache()),
1573 manager_(cache_
.get(), kMaxVaryingVectors
),
1574 vertex_shader_(NULL
),
1575 fragment_shader_(NULL
),
1578 virtual ~ProgramManagerWithCacheTest() {
1579 manager_
.Destroy(false);
1580 shader_manager_
.Destroy(false);
1584 virtual void SetUp() {
1585 GpuServiceTest::SetUp();
1587 vertex_shader_
= shader_manager_
.CreateShader(
1588 kVertexShaderClientId
, kVertexShaderServiceId
, GL_VERTEX_SHADER
);
1589 fragment_shader_
= shader_manager_
.CreateShader(
1590 kFragmentShaderClientId
, kFragmentShaderServiceId
, GL_FRAGMENT_SHADER
);
1591 ASSERT_TRUE(vertex_shader_
!= NULL
);
1592 ASSERT_TRUE(fragment_shader_
!= NULL
);
1593 vertex_shader_
->UpdateSource("lka asjf bjajsdfj");
1594 fragment_shader_
->UpdateSource("lka asjf a fasgag 3rdsf3 bjajsdfj");
1596 program_
= manager_
.CreateProgram(
1597 kClientProgramId
, kServiceProgramId
);
1598 ASSERT_TRUE(program_
!= NULL
);
1600 program_
->AttachShader(&shader_manager_
, vertex_shader_
);
1601 program_
->AttachShader(&shader_manager_
, fragment_shader_
);
1604 void SetShadersCompiled() {
1605 vertex_shader_
->SetStatus(true, NULL
, NULL
);
1606 fragment_shader_
->SetStatus(true, NULL
, NULL
);
1609 void SetProgramCached() {
1610 cache_
->LinkedProgramCacheSuccess(
1611 vertex_shader_
->source()->c_str(),
1613 fragment_shader_
->source()->c_str(),
1615 &program_
->bind_attrib_location_map());
1618 void SetExpectationsForProgramCached() {
1619 SetExpectationsForProgramCached(program_
,
1624 void SetExpectationsForProgramCached(
1626 Shader
* vertex_shader
,
1627 Shader
* fragment_shader
) {
1628 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
1629 program
->service_id(),
1634 &program
->bind_attrib_location_map(),
1638 void SetExpectationsForNotCachingProgram() {
1639 SetExpectationsForNotCachingProgram(program_
,
1644 void SetExpectationsForNotCachingProgram(
1646 Shader
* vertex_shader
,
1647 Shader
* fragment_shader
) {
1648 EXPECT_CALL(*cache_
.get(), SaveLinkedProgram(
1649 program
->service_id(),
1654 &program
->bind_attrib_location_map(),
1658 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result
) {
1659 SetExpectationsForProgramLoad(kServiceProgramId
,
1666 void SetExpectationsForProgramLoad(
1667 GLuint service_program_id
,
1669 Shader
* vertex_shader
,
1670 Shader
* fragment_shader
,
1671 ProgramCache::ProgramLoadResult result
) {
1672 EXPECT_CALL(*cache_
.get(),
1673 LoadLinkedProgram(service_program_id
,
1678 &program
->bind_attrib_location_map(),
1680 .WillOnce(Return(result
));
1683 void SetExpectationsForProgramLoadSuccess() {
1684 SetExpectationsForProgramLoadSuccess(kServiceProgramId
);
1687 void SetExpectationsForProgramLoadSuccess(GLuint service_program_id
) {
1688 TestHelper::SetupProgramSuccessExpectations(gl_
.get(),
1693 service_program_id
);
1696 void SetExpectationsForProgramLink() {
1697 SetExpectationsForProgramLink(kServiceProgramId
);
1700 void SetExpectationsForProgramLink(GLuint service_program_id
) {
1701 TestHelper::SetupShader(gl_
.get(), NULL
, 0, NULL
, 0, service_program_id
);
1702 if (gfx::g_driver_gl
.ext
.b_GL_ARB_get_program_binary
) {
1703 EXPECT_CALL(*gl_
.get(),
1704 ProgramParameteri(service_program_id
,
1705 PROGRAM_BINARY_RETRIEVABLE_HINT
,
1710 void SetExpectationsForSuccessCompile(
1711 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(1);
1716 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
1717 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1718 .WillOnce(SetArgumentPointee
<2>(GL_TRUE
));
1721 void SetExpectationsForNoCompile(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(0);
1726 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(0);
1727 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1731 void SetExpectationsForErrorCompile(const Shader
* shader
) {
1732 const GLuint shader_id
= shader
->service_id();
1733 const char* src
= shader
->source()->c_str();
1734 EXPECT_CALL(*gl_
.get(),
1735 ShaderSource(shader_id
, 1, Pointee(src
), NULL
)).Times(1);
1736 EXPECT_CALL(*gl_
.get(), CompileShader(shader_id
)).Times(1);
1737 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_COMPILE_STATUS
, _
))
1738 .WillOnce(SetArgumentPointee
<2>(GL_FALSE
));
1739 EXPECT_CALL(*gl_
.get(), GetShaderiv(shader_id
, GL_INFO_LOG_LENGTH
, _
))
1740 .WillOnce(SetArgumentPointee
<2>(0));
1741 EXPECT_CALL(*gl_
.get(), GetShaderInfoLog(shader_id
, 0, _
, _
))
1745 scoped_ptr
<MockProgramCache
> cache_
;
1746 ProgramManager manager_
;
1748 Shader
* vertex_shader_
;
1749 Shader
* fragment_shader_
;
1751 ShaderManager shader_manager_
;
1754 // GCC requires these declarations, but MSVC requires they not be present
1755 #ifndef COMPILER_MSVC
1756 const GLuint
ProgramManagerWithCacheTest::kClientProgramId
;
1757 const GLuint
ProgramManagerWithCacheTest::kServiceProgramId
;
1758 const GLuint
ProgramManagerWithCacheTest::kVertexShaderClientId
;
1759 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderClientId
;
1760 const GLuint
ProgramManagerWithCacheTest::kVertexShaderServiceId
;
1761 const GLuint
ProgramManagerWithCacheTest::kFragmentShaderServiceId
;
1764 TEST_F(ProgramManagerWithCacheTest
, CacheProgramOnSuccessfulLink
) {
1765 SetShadersCompiled();
1766 SetExpectationsForProgramLink();
1767 SetExpectationsForProgramCached();
1768 EXPECT_TRUE(program_
->Link(NULL
, NULL
, NULL
,
1769 Program::kCountOnlyStaticallyUsed
, base::Bind(&ShaderCacheCb
)));
1772 TEST_F(ProgramManagerWithCacheTest
, LoadProgramOnProgramCacheHit
) {
1773 SetShadersCompiled();
1776 SetExpectationsForNoCompile(vertex_shader_
);
1777 SetExpectationsForNoCompile(fragment_shader_
);
1778 SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS
);
1779 SetExpectationsForNotCachingProgram();
1780 SetExpectationsForProgramLoadSuccess();
1782 EXPECT_TRUE(program_
->Link(NULL
, NULL
, NULL
,
1783 Program::kCountOnlyStaticallyUsed
, base::Bind(&ShaderCacheCb
)));
1786 } // namespace gles2