Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / gpu / command_buffer / service / program_manager_unittest.cc
blob8c18b8f8d68ef7eb6c138edecc2d9869f4795903
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 // 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
42 #endif
44 namespace gpu {
45 namespace gles2 {
47 namespace {
48 const uint32 kMaxVaryingVectors = 8;
50 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
51 } // namespace anonymous
53 class ProgramManagerTest : public GpuServiceTest {
54 public:
55 ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
56 virtual ~ProgramManagerTest() {
57 manager_.Destroy(false);
60 protected:
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);
73 GLuint client_id = 0;
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))
90 .Times(1)
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))
116 .Times(1)
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 {
139 public:
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;
208 protected:
209 typedef TestHelper::AttribInfo AttribInfo;
210 typedef TestHelper::UniformInfo UniformInfo;
212 typedef enum {
213 kVarUniform,
214 kVarVarying,
215 kVarAttribute
216 } VarCategory;
218 typedef struct {
219 int type;
220 int size;
221 int precision;
222 int static_use;
223 std::string name;
224 VarCategory category;
225 } VarInfo;
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,
237 GL_FRAGMENT_SHADER);
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,
255 GLuint service_id) {
256 TestHelper::SetupShader(
257 gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
260 void SetupDefaultShaderExpectations() {
261 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
262 kServiceProgramId);
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,
277 service_id);
279 program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
280 base::Bind(&ShaderCacheCb));
281 GLint link_status;
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) {
290 // Set up shader
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) {
303 case kVarAttribute:
304 map = &vertex_attrib_map;
305 break;
306 case kVarUniform:
307 map = &vertex_uniform_map;
308 break;
309 case kVarVarying:
310 map = &vertex_varying_map;
311 break;
312 default:
313 NOTREACHED();
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) {
339 case kVarAttribute:
340 map = &frag_attrib_map;
341 break;
342 case kVarUniform:
343 map = &frag_uniform_map;
344 break;
345 case kVarVarying:
346 map = &frag_varying_map;
347 break;
348 default:
349 NOTREACHED();
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);
375 // Set Status
376 vshader->SetStatus(true, "", &vertex_shader_translator);
377 fshader->SetStatus(true, "", &frag_shader_translator);
379 // Set up program
380 const GLuint kClientProgramId = 6666;
381 const GLuint kServiceProgramId = 8888;
382 Program* program =
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));
387 return program;
390 static AttribInfo kAttribs[];
391 static UniformInfo kUniforms[];
393 ProgramManager manager_;
394 Program* program_;
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;
442 #endif
444 const size_t ProgramManagerWithShaderTest::kNumAttribs =
445 arraysize(ProgramManagerWithShaderTest::kAttribs);
447 ProgramManagerWithShaderTest::UniformInfo
448 ProgramManagerWithShaderTest::kUniforms[] = {
449 { kUniform1Name,
450 kUniform1Size,
451 kUniform1Type,
452 kUniform1FakeLocation,
453 kUniform1RealLocation,
454 kUniform1DesiredLocation,
455 kUniform1Name,
457 { kUniform2Name,
458 kUniform2Size,
459 kUniform2Type,
460 kUniform2FakeLocation,
461 kUniform2RealLocation,
462 kUniform2DesiredLocation,
463 kUniform2Name,
465 { kUniform3BadName,
466 kUniform3Size,
467 kUniform3Type,
468 kUniform3FakeLocation,
469 kUniform3RealLocation,
470 kUniform3DesiredLocation,
471 kUniform3GoodName,
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
617 // "uniform2[0]"
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);
647 real_location = -1;
648 array_index = -1;
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[] = {
668 { kUniform1Name,
669 kUniform1Size,
670 kUniform1Type,
671 kUniform1FakeLocation,
672 kUniform1RealLocation,
673 kUniform1DesiredLocation,
674 kUniform1Name,
676 { kUniform2Name,
677 kUniform2Size,
678 kUniform2Type,
679 kUniform2FakeLocation,
680 kUniform2RealLocation,
681 kUniform2DesiredLocation,
682 kUniform2Name,
684 { kUniform3BadName,
685 kUniform3Size,
686 kUniform3Type,
687 kUniform3FakeLocation,
688 kUniform3RealLocation,
689 kUniform3DesiredLocation,
690 kUniform3GoodName,
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;
700 SetupShader(
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);
710 Program* program =
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));
717 GLint value = 0;
718 program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
719 EXPECT_EQ(3, value);
720 // Check that we skipped the "gl_" uniform.
721 program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
722 EXPECT_EQ(2, 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[] = {
737 { kUniform1Name,
738 kUniform1Size,
739 kUniform1Type,
740 kUniform1FakeLocation,
741 kUniform1RealLocation,
742 kUniform1DesiredLocation,
743 kUniform1Name,
745 { kUniform2Name,
746 kUniform2Size,
747 kUniform2Type,
748 kUniform2FakeLocation,
749 kUniform2RealLocation,
750 kUniform2DesiredLocation,
751 kUniform2Name,
753 { kUniform3Name,
754 kUniform3Size,
755 kUniform3Type,
756 kUniform3FakeLocation,
757 kUniform3RealLocation,
758 kUniform3DesiredLocation,
759 kUniform3Name,
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;
769 SetupShader(
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);
779 Program* program =
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[] = {
850 { kUniform1Name,
851 kUniform1Size,
852 kUniform1Type,
853 kUniform1FakeLocation,
854 kUniform1RealLocation,
855 kUniform1DesiredLocation,
856 kUniform1Name,
858 { kUniform2Name,
859 kUniform2Size,
860 kUniform2BadType,
861 kUniform2FakeLocation,
862 kUniform2RealLocation,
863 kUniform2DesiredLocation,
864 kUniform2Name,
866 { kUniform3BadName,
867 kUniform3Size,
868 kUniform3Type,
869 kUniform3FakeLocation,
870 kUniform3RealLocation,
871 kUniform3DesiredLocation,
872 kUniform3GoodName,
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,
880 kServiceProgramId);
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.
889 // Check Attribs
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(
895 attrib_info->name);
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);
902 // Check Uniforms
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(
908 uniform_info->name);
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))
957 .Times(1)
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))
1006 .Times(1)
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*>(
1027 sizeof(*header),
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());
1045 ++input;
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) {
1056 EXPECT_EQ(
1057 ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1058 locations[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());
1065 ++input;
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*>(
1096 sizeof(*header),
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);
1106 EXPECT_EQ(
1107 ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1108 locations[0]);
1109 for (int32 jj = 1; jj < input->size; ++jj)
1110 EXPECT_EQ(-1, locations[jj]);
1111 ++input;
1115 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1116 // Set up shader
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(
1125 kAttribs[ii].type,
1126 kAttribs[ii].size,
1127 SH_PRECISION_MEDIUMP,
1128 kAttribStaticUse,
1129 kAttribs[ii].name);
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);
1149 // Set Status
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);
1165 // Set up program
1166 const GLuint kClientProgramId = 6666;
1167 const GLuint kServiceProgramId = 8888;
1168 Program* program =
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) {
1195 // Set up shader
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);
1240 // Set Status
1241 vshader->SetStatus(true, "", &vertex_shader_translator);
1242 fshader->SetStatus(true, "", &frag_shader_translator);
1244 // Set up program
1245 const GLuint kClientProgramId = 6666;
1246 const GLuint kServiceProgramId = 8888;
1247 Program* program =
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
1328 // succeed.
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
1344 // failure.
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);
1373 EXPECT_FALSE(
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);
1391 EXPECT_TRUE(
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[] = {
1435 GL_SAMPLER_2D,
1436 GL_SAMPLER_CUBE,
1437 GL_SAMPLER_EXTERNAL_OES,
1438 GL_SAMPLER_3D_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[] = {
1449 { kUniform1Name,
1450 kUniform1Size,
1451 kUniform1Type,
1452 kUniform1FakeLocation,
1453 kUniform1RealLocation,
1454 kUniform1DesiredLocation,
1455 kUniform1Name,
1457 { kUniform2Name,
1458 kUniform2Size,
1459 kSamplerTypes[ii],
1460 kUniform2FakeLocation,
1461 kUniform2RealLocation,
1462 kUniform2DesiredLocation,
1463 kUniform2Name,
1465 { kUniform3BadName,
1466 kUniform3Size,
1467 kUniform3Type,
1468 kUniform3FakeLocation,
1469 kUniform3RealLocation,
1470 kUniform3DesiredLocation,
1471 kUniform3GoodName,
1474 const size_t kNumAttribs = arraysize(kAttribs);
1475 const size_t kNumUniforms = arraysize(kUniforms);
1476 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1477 kServiceProgramId);
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[] = {
1521 { kUniform1Name,
1522 kUniform1Size,
1523 kUniform1Type,
1524 kUniform1FakeLocation,
1525 kUniform1RealLocation,
1526 kUniform1DesiredLocation,
1527 kUniform1Name,
1529 { kUniform2Name,
1530 kUniform2Size,
1531 kUniform2Type,
1532 kUniform2FakeLocation,
1533 kUniform2RealLocation,
1534 kUniform2DesiredLocation,
1535 kUniform2Name,
1537 { kUniform3BadName,
1538 kUniform3Size,
1539 kUniform3Type,
1540 kUniform3FakeLocation,
1541 kUniform3RealLocation,
1542 kUniform3DesiredLocation,
1543 kUniform3GoodName,
1547 const size_t kNumAttribs = arraysize(kAttribs);
1548 const size_t kNumUniforms = arraysize(kUniforms);
1549 SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1550 kServiceProgramId);
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 {
1563 public:
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),
1576 program_(NULL) {
1578 virtual ~ProgramManagerWithCacheTest() {
1579 manager_.Destroy(false);
1580 shader_manager_.Destroy(false);
1583 protected:
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(),
1612 NULL,
1613 fragment_shader_->source()->c_str(),
1614 NULL,
1615 &program_->bind_attrib_location_map());
1618 void SetExpectationsForProgramCached() {
1619 SetExpectationsForProgramCached(program_,
1620 vertex_shader_,
1621 fragment_shader_);
1624 void SetExpectationsForProgramCached(
1625 Program* program,
1626 Shader* vertex_shader,
1627 Shader* fragment_shader) {
1628 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1629 program->service_id(),
1630 vertex_shader,
1631 NULL,
1632 fragment_shader,
1633 NULL,
1634 &program->bind_attrib_location_map(),
1635 _)).Times(1);
1638 void SetExpectationsForNotCachingProgram() {
1639 SetExpectationsForNotCachingProgram(program_,
1640 vertex_shader_,
1641 fragment_shader_);
1644 void SetExpectationsForNotCachingProgram(
1645 Program* program,
1646 Shader* vertex_shader,
1647 Shader* fragment_shader) {
1648 EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1649 program->service_id(),
1650 vertex_shader,
1651 NULL,
1652 fragment_shader,
1653 NULL,
1654 &program->bind_attrib_location_map(),
1655 _)).Times(0);
1658 void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
1659 SetExpectationsForProgramLoad(kServiceProgramId,
1660 program_,
1661 vertex_shader_,
1662 fragment_shader_,
1663 result);
1666 void SetExpectationsForProgramLoad(
1667 GLuint service_program_id,
1668 Program* program,
1669 Shader* vertex_shader,
1670 Shader* fragment_shader,
1671 ProgramCache::ProgramLoadResult result) {
1672 EXPECT_CALL(*cache_.get(),
1673 LoadLinkedProgram(service_program_id,
1674 vertex_shader,
1675 NULL,
1676 fragment_shader,
1677 NULL,
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(),
1689 NULL,
1691 NULL,
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,
1706 GL_TRUE)).Times(1);
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, _))
1728 .Times(0);
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, _, _))
1742 .Times(1);
1745 scoped_ptr<MockProgramCache> cache_;
1746 ProgramManager manager_;
1748 Shader* vertex_shader_;
1749 Shader* fragment_shader_;
1750 Program* program_;
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;
1762 #endif
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();
1774 SetProgramCached();
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
1787 } // namespace gpu