Remove the now unused TextButton code.
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blob326486108b10bc773883587fd815ae40673617d4
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"
7 #include <algorithm>
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"
23 using ::testing::_;
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 namespace gpu {
35 namespace gles2 {
37 namespace {
38 const uint32 kMaxVaryingVectors = 8;
40 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
41 } // namespace anonymous
43 class ProgramManagerTest : public GpuServiceTest {
44 public:
45 ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
46 virtual ~ProgramManagerTest() {
47 manager_.Destroy(false);
50 protected:
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);
63 GLuint client_id = 0;
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))
80 .Times(1)
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))
106 .Times(1)
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 {
129 public:
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;
198 protected:
199 typedef TestHelper::AttribInfo AttribInfo;
200 typedef TestHelper::UniformInfo UniformInfo;
202 typedef enum {
203 kVarUniform,
204 kVarVarying,
205 kVarAttribute
206 } VarCategory;
208 typedef struct {
209 int type;
210 int size;
211 int precision;
212 int static_use;
213 std::string name;
214 VarCategory category;
215 } VarInfo;
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,
227 GL_FRAGMENT_SHADER);
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,
245 GLuint service_id) {
246 TestHelper::SetupShader(
247 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
250 void SetupDefaultShaderExpectations() {
251 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
252 kServiceProgramId);
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,
267 service_id);
269 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
270 base::Bind(&ShaderCacheCb));
271 GLint link_status;
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) {
280 // Set up shader
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) {
293 case kVarAttribute:
294 map = &vertex_attrib_map;
295 break;
296 case kVarUniform:
297 map = &vertex_uniform_map;
298 break;
299 case kVarVarying:
300 map = &vertex_varying_map;
301 break;
302 default:
303 NOTREACHED();
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) {
329 case kVarAttribute:
330 map = &frag_attrib_map;
331 break;
332 case kVarUniform:
333 map = &frag_uniform_map;
334 break;
335 case kVarVarying:
336 map = &frag_varying_map;
337 break;
338 default:
339 NOTREACHED();
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);
365 // Set Status
366 vshader->SetStatus(true, "", &vertex_shader_translator);
367 fshader->SetStatus(true, "", &frag_shader_translator);
369 // Set up program
370 const GLuint kClientProgramId = 6666;
371 const GLuint kServiceProgramId = 8888;
372 Program* program =
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));
377 return program;
380 static AttribInfo kAttribs[];
381 static UniformInfo kUniforms[];
383 ProgramManager manager_;
384 Program* program_;
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;
432 #endif
434 const size_t ProgramManagerWithShaderTest::kNumAttribs =
435 arraysize(ProgramManagerWithShaderTest::kAttribs);
437 ProgramManagerWithShaderTest::UniformInfo
438 ProgramManagerWithShaderTest::kUniforms[] = {
439 { kUniform1Name,
440 kUniform1Size,
441 kUniform1Type,
442 kUniform1FakeLocation,
443 kUniform1RealLocation,
444 kUniform1DesiredLocation,
445 kUniform1Name,
447 { kUniform2Name,
448 kUniform2Size,
449 kUniform2Type,
450 kUniform2FakeLocation,
451 kUniform2RealLocation,
452 kUniform2DesiredLocation,
453 kUniform2Name,
455 { kUniform3BadName,
456 kUniform3Size,
457 kUniform3Type,
458 kUniform3FakeLocation,
459 kUniform3RealLocation,
460 kUniform3DesiredLocation,
461 kUniform3GoodName,
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
607 // "uniform2[0]"
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);
637 real_location = -1;
638 array_index = -1;
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[] = {
658 { kUniform1Name,
659 kUniform1Size,
660 kUniform1Type,
661 kUniform1FakeLocation,
662 kUniform1RealLocation,
663 kUniform1DesiredLocation,
664 kUniform1Name,
666 { kUniform2Name,
667 kUniform2Size,
668 kUniform2Type,
669 kUniform2FakeLocation,
670 kUniform2RealLocation,
671 kUniform2DesiredLocation,
672 kUniform2Name,
674 { kUniform3BadName,
675 kUniform3Size,
676 kUniform3Type,
677 kUniform3FakeLocation,
678 kUniform3RealLocation,
679 kUniform3DesiredLocation,
680 kUniform3GoodName,
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;
690 SetupShader(
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);
700 Program* program =
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));
707 GLint value = 0;
708 program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
709 EXPECT_EQ(3, value);
710 // Check that we skipped the "gl_" uniform.
711 program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
712 EXPECT_EQ(2, 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[] = {
727 { kUniform1Name,
728 kUniform1Size,
729 kUniform1Type,
730 kUniform1FakeLocation,
731 kUniform1RealLocation,
732 kUniform1DesiredLocation,
733 kUniform1Name,
735 { kUniform2Name,
736 kUniform2Size,
737 kUniform2Type,
738 kUniform2FakeLocation,
739 kUniform2RealLocation,
740 kUniform2DesiredLocation,
741 kUniform2Name,
743 { kUniform3Name,
744 kUniform3Size,
745 kUniform3Type,
746 kUniform3FakeLocation,
747 kUniform3RealLocation,
748 kUniform3DesiredLocation,
749 kUniform3Name,
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;
759 SetupShader(
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);
769 Program* program =
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[] = {
840 { kUniform1Name,
841 kUniform1Size,
842 kUniform1Type,
843 kUniform1FakeLocation,
844 kUniform1RealLocation,
845 kUniform1DesiredLocation,
846 kUniform1Name,
848 { kUniform2Name,
849 kUniform2Size,
850 kUniform2BadType,
851 kUniform2FakeLocation,
852 kUniform2RealLocation,
853 kUniform2DesiredLocation,
854 kUniform2Name,
856 { kUniform3BadName,
857 kUniform3Size,
858 kUniform3Type,
859 kUniform3FakeLocation,
860 kUniform3RealLocation,
861 kUniform3DesiredLocation,
862 kUniform3GoodName,
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,
870 kServiceProgramId);
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.
879 // Check Attribs
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(
885 attrib_info->name);
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);
892 // Check Uniforms
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(
898 uniform_info->name);
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))
947 .Times(1)
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))
996 .Times(1)
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*>(
1017 sizeof(*header),
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());
1035 ++input;
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) {
1046 EXPECT_EQ(
1047 ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1048 locations[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());
1055 ++input;
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*>(
1086 sizeof(*header),
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);
1096 EXPECT_EQ(
1097 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1098 locations[0]);
1099 for (int32 jj = 1; jj < input->size; ++jj)
1100 EXPECT_EQ(-1, locations[jj]);
1101 ++input;
1105 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1106 // Set up shader
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(
1115 kAttribs[ii].type,
1116 kAttribs[ii].size,
1117 SH_PRECISION_MEDIUMP,
1118 kAttribStaticUse,
1119 kAttribs[ii].name);
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);
1139 // Set Status
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);
1155 // Set up program
1156 const GLuint kClientProgramId = 6666;
1157 const GLuint kServiceProgramId = 8888;
1158 Program* program =
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) {
1185 // Set up shader
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);
1230 // Set Status
1231 vshader->SetStatus(true, "", &vertex_shader_translator);
1232 fshader->SetStatus(true, "", &frag_shader_translator);
1234 // Set up program
1235 const GLuint kClientProgramId = 6666;
1236 const GLuint kServiceProgramId = 8888;
1237 Program* program =
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
1318 // succeed.
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
1334 // failure.
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);
1363 EXPECT_FALSE(
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);
1381 EXPECT_TRUE(
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[] = {
1425 GL_SAMPLER_2D,
1426 GL_SAMPLER_CUBE,
1427 GL_SAMPLER_EXTERNAL_OES,
1428 GL_SAMPLER_3D_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[] = {
1439 { kUniform1Name,
1440 kUniform1Size,
1441 kUniform1Type,
1442 kUniform1FakeLocation,
1443 kUniform1RealLocation,
1444 kUniform1DesiredLocation,
1445 kUniform1Name,
1447 { kUniform2Name,
1448 kUniform2Size,
1449 kSamplerTypes[ii],
1450 kUniform2FakeLocation,
1451 kUniform2RealLocation,
1452 kUniform2DesiredLocation,
1453 kUniform2Name,
1455 { kUniform3BadName,
1456 kUniform3Size,
1457 kUniform3Type,
1458 kUniform3FakeLocation,
1459 kUniform3RealLocation,
1460 kUniform3DesiredLocation,
1461 kUniform3GoodName,
1464 const size_t kNumAttribs = arraysize(kAttribs);
1465 const size_t kNumUniforms = arraysize(kUniforms);
1466 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1467 kServiceProgramId);
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[] = {
1511 { kUniform1Name,
1512 kUniform1Size,
1513 kUniform1Type,
1514 kUniform1FakeLocation,
1515 kUniform1RealLocation,
1516 kUniform1DesiredLocation,
1517 kUniform1Name,
1519 { kUniform2Name,
1520 kUniform2Size,
1521 kUniform2Type,
1522 kUniform2FakeLocation,
1523 kUniform2RealLocation,
1524 kUniform2DesiredLocation,
1525 kUniform2Name,
1527 { kUniform3BadName,
1528 kUniform3Size,
1529 kUniform3Type,
1530 kUniform3FakeLocation,
1531 kUniform3RealLocation,
1532 kUniform3DesiredLocation,
1533 kUniform3GoodName,
1537 const size_t kNumAttribs = arraysize(kAttribs);
1538 const size_t kNumUniforms = arraysize(kUniforms);
1539 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1540 kServiceProgramId);
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 {
1553 public:
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),
1566 program_(NULL) {
1568 virtual ~ProgramManagerWithCacheTest() {
1569 manager_.Destroy(false);
1570 shader_manager_.Destroy(false);
1573 protected:
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(),
1602 NULL,
1603 fragment_shader_->source()->c_str(),
1604 NULL,
1605 &program_->bind_attrib_location_map());
1608 void SetExpectationsForProgramCached() {
1609 SetExpectationsForProgramCached(program_,
1610 vertex_shader_,
1611 fragment_shader_);
1614 void SetExpectationsForProgramCached(
1615 Program* program,
1616 Shader* vertex_shader,
1617 Shader* fragment_shader) {
1618 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1619 program->service_id(),
1620 vertex_shader,
1621 NULL,
1622 fragment_shader,
1623 NULL,
1624 &program->bind_attrib_location_map(),
1625 _)).Times(1);
1628 void SetExpectationsForNotCachingProgram() {
1629 SetExpectationsForNotCachingProgram(program_,
1630 vertex_shader_,
1631 fragment_shader_);
1634 void SetExpectationsForNotCachingProgram(
1635 Program* program,
1636 Shader* vertex_shader,
1637 Shader* fragment_shader) {
1638 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1639 program->service_id(),
1640 vertex_shader,
1641 NULL,
1642 fragment_shader,
1643 NULL,
1644 &program->bind_attrib_location_map(),
1645 _)).Times(0);
1648 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
1649 SetExpectationsForProgramLoad(kServiceProgramId,
1650 program_,
1651 vertex_shader_,
1652 fragment_shader_,
1653 result);
1656 void SetExpectationsForProgramLoad(
1657 GLuint service_program_id,
1658 Program* program,
1659 Shader* vertex_shader,
1660 Shader* fragment_shader,
1661 ProgramCache::ProgramLoadResult result) {
1662 EXPECT_CALL(*cache_.get(),
1663 LoadLinkedProgram(service_program_id,
1664 vertex_shader,
1665 NULL,
1666 fragment_shader,
1667 NULL,
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(),
1679 NULL,
1681 NULL,
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,
1696 GL_TRUE)).Times(1);
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, _))
1718 .Times(0);
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, _, _))
1732 .Times(1);
1735 scoped_ptr<MockProgramCache> cache_;
1736 ProgramManager manager_;
1738 Shader* vertex_shader_;
1739 Shader* fragment_shader_;
1740 Program* program_;
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;
1752 #endif
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();
1764 SetProgramCached();
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
1777 } // namespace gpu