Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / program_manager_unittest.cc
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.
4
5 #include "gpu/command_buffer/service/program_manager.h"
6
7 #include <algorithm>
8
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"
22
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;
33
34 namespace gpu {
35 namespace gles2 {
36
37 namespace {
38 const uint32 kMaxVaryingVectors = 8;
39
40 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
41 }  // namespace anonymous
42
43 class ProgramManagerTest : public GpuServiceTest {
44  public:
45   ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
46   virtual ~ProgramManagerTest() {
47     manager_.Destroy(false);
48   }
49
50  protected:
51   ProgramManager manager_;
52 };
53
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);
68 }
69
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);
86 }
87
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()));
111 }
112
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);
126 }
127
128 class ProgramManagerWithShaderTest : public GpuServiceTest {
129  public:
130   ProgramManagerWithShaderTest()
131       :  manager_(NULL, kMaxVaryingVectors), program_(NULL) {
132   }
133
134   virtual ~ProgramManagerWithShaderTest() {
135     manager_.Destroy(false);
136     shader_manager_.Destroy(false);
137   }
138
139   static const GLint kNumVertexAttribs = 16;
140
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;
147
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;
166
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;
194
195   static const size_t kNumAttribs;
196   static const size_t kNumUniforms;
197
198  protected:
199   typedef TestHelper::AttribInfo AttribInfo;
200   typedef TestHelper::UniformInfo UniformInfo;
201
202   typedef enum {
203     kVarUniform,
204     kVarVarying,
205     kVarAttribute
206   } VarCategory;
207
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;
216
217   virtual void SetUp() {
218     GpuServiceTest::SetUp();
219
220     SetupDefaultShaderExpectations();
221
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     TestHelper::SetShaderStates(gl_.get(), vertex_shader, true);
231     TestHelper::SetShaderStates(gl_.get(), fragment_shader, true);
232
233     program_ = manager_.CreateProgram(
234         kClientProgramId, kServiceProgramId);
235     ASSERT_TRUE(program_ != NULL);
236
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));
241   }
242
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);
248   }
249
250   void SetupDefaultShaderExpectations() {
251     SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
252                 kServiceProgramId);
253   }
254
255   void SetupExpectationsForClearingUniforms(
256       UniformInfo* uniforms, size_t num_uniforms) {
257     TestHelper::SetupExpectationsForClearingUniforms(
258         gl_.get(), uniforms, num_uniforms);
259   }
260
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);
268     }
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);
274   }
275
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;
285
286     ShaderTranslator::VariableMap vertex_attrib_map;
287     ShaderTranslator::VariableMap vertex_uniform_map;
288     ShaderTranslator::VariableMap vertex_varying_map;
289     for (size_t ii = 0; ii < vertex_variable_size; ++ii) {
290       ShaderTranslator::VariableMap* map = NULL;
291       switch (vertex_variables[ii].category) {
292         case kVarAttribute:
293           map = &vertex_attrib_map;
294           break;
295         case kVarUniform:
296           map = &vertex_uniform_map;
297           break;
298         case kVarVarying:
299           map = &vertex_varying_map;
300           break;
301         default:
302           NOTREACHED();
303       }
304       (*map)[vertex_variables[ii].name] =
305           ShaderTranslator::VariableInfo(vertex_variables[ii].type,
306                                          vertex_variables[ii].size,
307                                          vertex_variables[ii].precision,
308                                          vertex_variables[ii].static_use,
309                                          vertex_variables[ii].name);
310     }
311
312     ShaderTranslator::VariableMap frag_attrib_map;
313     ShaderTranslator::VariableMap frag_uniform_map;
314     ShaderTranslator::VariableMap frag_varying_map;
315     for (size_t ii = 0; ii < fragment_variable_size; ++ii) {
316       ShaderTranslator::VariableMap* map = NULL;
317       switch (fragment_variables[ii].category) {
318         case kVarAttribute:
319           map = &frag_attrib_map;
320           break;
321         case kVarUniform:
322           map = &frag_uniform_map;
323           break;
324         case kVarVarying:
325           map = &frag_varying_map;
326           break;
327         default:
328           NOTREACHED();
329       }
330       (*map)[fragment_variables[ii].name] =
331           ShaderTranslator::VariableInfo(fragment_variables[ii].type,
332                                          fragment_variables[ii].size,
333                                          fragment_variables[ii].precision,
334                                          fragment_variables[ii].static_use,
335                                          fragment_variables[ii].name);
336     }
337
338     // Check we can create shader.
339     Shader* vshader = shader_manager_.CreateShader(
340         kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
341     Shader* fshader = shader_manager_.CreateShader(
342         kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
343     // Check shader got created.
344     EXPECT_TRUE(vshader != NULL && fshader != NULL);
345     // Set Status
346     TestHelper::SetShaderStates(
347         gl_.get(), vshader, true, NULL, NULL,
348         &vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map, NULL);
349     TestHelper::SetShaderStates(
350         gl_.get(), fshader, true, NULL, NULL,
351         &frag_attrib_map, &frag_uniform_map, &frag_varying_map, NULL);
352
353     // Set up program
354     const GLuint kClientProgramId = 6666;
355     const GLuint kServiceProgramId = 8888;
356     Program* program =
357         manager_.CreateProgram(kClientProgramId, kServiceProgramId);
358     EXPECT_TRUE(program != NULL);
359     EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
360     EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
361     return program;
362   }
363
364   static AttribInfo kAttribs[];
365   static UniformInfo kUniforms[];
366
367   ProgramManager manager_;
368   Program* program_;
369   ShaderManager shader_manager_;
370 };
371
372 ProgramManagerWithShaderTest::AttribInfo
373     ProgramManagerWithShaderTest::kAttribs[] = {
374   { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
375   { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
376   { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
377 };
378
379 // GCC requires these declarations, but MSVC requires they not be present
380 #ifndef COMPILER_MSVC
381 const GLint ProgramManagerWithShaderTest::kNumVertexAttribs;
382 const GLuint ProgramManagerWithShaderTest::kClientProgramId;
383 const GLuint ProgramManagerWithShaderTest::kServiceProgramId;
384 const GLuint ProgramManagerWithShaderTest::kVertexShaderClientId;
385 const GLuint ProgramManagerWithShaderTest::kFragmentShaderClientId;
386 const GLuint ProgramManagerWithShaderTest::kVertexShaderServiceId;
387 const GLuint ProgramManagerWithShaderTest::kFragmentShaderServiceId;
388 const GLint ProgramManagerWithShaderTest::kAttrib1Size;
389 const GLint ProgramManagerWithShaderTest::kAttrib2Size;
390 const GLint ProgramManagerWithShaderTest::kAttrib3Size;
391 const GLint ProgramManagerWithShaderTest::kAttrib1Location;
392 const GLint ProgramManagerWithShaderTest::kAttrib2Location;
393 const GLint ProgramManagerWithShaderTest::kAttrib3Location;
394 const GLenum ProgramManagerWithShaderTest::kAttrib1Type;
395 const GLenum ProgramManagerWithShaderTest::kAttrib2Type;
396 const GLenum ProgramManagerWithShaderTest::kAttrib3Type;
397 const GLint ProgramManagerWithShaderTest::kInvalidAttribLocation;
398 const GLint ProgramManagerWithShaderTest::kBadAttribIndex;
399 const GLint ProgramManagerWithShaderTest::kUniform1Size;
400 const GLint ProgramManagerWithShaderTest::kUniform2Size;
401 const GLint ProgramManagerWithShaderTest::kUniform3Size;
402 const GLint ProgramManagerWithShaderTest::kUniform1FakeLocation;
403 const GLint ProgramManagerWithShaderTest::kUniform2FakeLocation;
404 const GLint ProgramManagerWithShaderTest::kUniform3FakeLocation;
405 const GLint ProgramManagerWithShaderTest::kUniform1RealLocation;
406 const GLint ProgramManagerWithShaderTest::kUniform2RealLocation;
407 const GLint ProgramManagerWithShaderTest::kUniform3RealLocation;
408 const GLint ProgramManagerWithShaderTest::kUniform1DesiredLocation;
409 const GLint ProgramManagerWithShaderTest::kUniform2DesiredLocation;
410 const GLint ProgramManagerWithShaderTest::kUniform3DesiredLocation;
411 const GLenum ProgramManagerWithShaderTest::kUniform1Type;
412 const GLenum ProgramManagerWithShaderTest::kUniform2Type;
413 const GLenum ProgramManagerWithShaderTest::kUniform3Type;
414 const GLint ProgramManagerWithShaderTest::kInvalidUniformLocation;
415 const GLint ProgramManagerWithShaderTest::kBadUniformIndex;
416 #endif
417
418 const size_t ProgramManagerWithShaderTest::kNumAttribs =
419     arraysize(ProgramManagerWithShaderTest::kAttribs);
420
421 ProgramManagerWithShaderTest::UniformInfo
422     ProgramManagerWithShaderTest::kUniforms[] = {
423   { kUniform1Name,
424     kUniform1Size,
425     kUniform1Type,
426     kUniform1FakeLocation,
427     kUniform1RealLocation,
428     kUniform1DesiredLocation,
429     kUniform1Name,
430   },
431   { kUniform2Name,
432     kUniform2Size,
433     kUniform2Type,
434     kUniform2FakeLocation,
435     kUniform2RealLocation,
436     kUniform2DesiredLocation,
437     kUniform2Name,
438   },
439   { kUniform3BadName,
440     kUniform3Size,
441     kUniform3Type,
442     kUniform3FakeLocation,
443     kUniform3RealLocation,
444     kUniform3DesiredLocation,
445     kUniform3GoodName,
446   },
447 };
448
449 const size_t ProgramManagerWithShaderTest::kNumUniforms =
450     arraysize(ProgramManagerWithShaderTest::kUniforms);
451
452 const char* ProgramManagerWithShaderTest::kAttrib1Name = "attrib1";
453 const char* ProgramManagerWithShaderTest::kAttrib2Name = "attrib2";
454 const char* ProgramManagerWithShaderTest::kAttrib3Name = "attrib3";
455 const char* ProgramManagerWithShaderTest::kUniform1Name = "uniform1";
456 // Correctly has array spec.
457 const char* ProgramManagerWithShaderTest::kUniform2Name = "uniform2[0]";
458 // Incorrectly missing array spec.
459 const char* ProgramManagerWithShaderTest::kUniform3BadName = "uniform3";
460 const char* ProgramManagerWithShaderTest::kUniform3GoodName = "uniform3[0]";
461
462 TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) {
463   const Program* program = manager_.GetProgram(kClientProgramId);
464   ASSERT_TRUE(program != NULL);
465   const Program::AttribInfoVector& infos =
466       program->GetAttribInfos();
467   ASSERT_EQ(kNumAttribs, infos.size());
468   for (size_t ii = 0; ii < kNumAttribs; ++ii) {
469     const Program::VertexAttrib& info = infos[ii];
470     const AttribInfo& expected = kAttribs[ii];
471     EXPECT_EQ(expected.size, info.size);
472     EXPECT_EQ(expected.type, info.type);
473     EXPECT_EQ(expected.location, info.location);
474     EXPECT_STREQ(expected.name, info.name.c_str());
475   }
476 }
477
478 TEST_F(ProgramManagerWithShaderTest, GetAttribInfo) {
479   const GLint kValidIndex = 1;
480   const GLint kInvalidIndex = 1000;
481   const Program* program = manager_.GetProgram(kClientProgramId);
482   ASSERT_TRUE(program != NULL);
483   const Program::VertexAttrib* info =
484       program->GetAttribInfo(kValidIndex);
485   ASSERT_TRUE(info != NULL);
486   EXPECT_EQ(kAttrib2Size, info->size);
487   EXPECT_EQ(kAttrib2Type, info->type);
488   EXPECT_EQ(kAttrib2Location, info->location);
489   EXPECT_STREQ(kAttrib2Name, info->name.c_str());
490   EXPECT_TRUE(program->GetAttribInfo(kInvalidIndex) == NULL);
491 }
492
493 TEST_F(ProgramManagerWithShaderTest, GetAttribLocation) {
494   const char* kInvalidName = "foo";
495   const Program* program = manager_.GetProgram(kClientProgramId);
496   ASSERT_TRUE(program != NULL);
497   EXPECT_EQ(kAttrib2Location, program->GetAttribLocation(kAttrib2Name));
498   EXPECT_EQ(-1, program->GetAttribLocation(kInvalidName));
499 }
500
501 TEST_F(ProgramManagerWithShaderTest, GetUniformInfo) {
502   const GLint kInvalidIndex = 1000;
503   const Program* program = manager_.GetProgram(kClientProgramId);
504   ASSERT_TRUE(program != NULL);
505   const Program::UniformInfo* info =
506       program->GetUniformInfo(0);
507   ASSERT_TRUE(info != NULL);
508   EXPECT_EQ(kUniform1Size, info->size);
509   EXPECT_EQ(kUniform1Type, info->type);
510   EXPECT_EQ(kUniform1RealLocation, info->element_locations[0]);
511   EXPECT_STREQ(kUniform1Name, info->name.c_str());
512   info = program->GetUniformInfo(1);
513   ASSERT_TRUE(info != NULL);
514   EXPECT_EQ(kUniform2Size, info->size);
515   EXPECT_EQ(kUniform2Type, info->type);
516   EXPECT_EQ(kUniform2RealLocation, info->element_locations[0]);
517   EXPECT_STREQ(kUniform2Name, info->name.c_str());
518   info = program->GetUniformInfo(2);
519   // We emulate certain OpenGL drivers by supplying the name without
520   // the array spec. Our implementation should correctly add the required spec.
521   ASSERT_TRUE(info != NULL);
522   EXPECT_EQ(kUniform3Size, info->size);
523   EXPECT_EQ(kUniform3Type, info->type);
524   EXPECT_EQ(kUniform3RealLocation, info->element_locations[0]);
525   EXPECT_STREQ(kUniform3GoodName, info->name.c_str());
526   EXPECT_TRUE(program->GetUniformInfo(kInvalidIndex) == NULL);
527 }
528
529 TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) {
530   static const GLuint kClientProgramId = 124;
531   static const GLuint kServiceProgramId = 457;
532   Program* program = manager_.CreateProgram(
533       kClientProgramId, kServiceProgramId);
534   ASSERT_TRUE(program != NULL);
535   EXPECT_FALSE(program->CanLink());
536   const GLuint kVShaderClientId = 2001;
537   const GLuint kFShaderClientId = 2002;
538   const GLuint kVShaderServiceId = 3001;
539   const GLuint kFShaderServiceId = 3002;
540   Shader* vshader = shader_manager_.CreateShader(
541       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
542   ASSERT_TRUE(vshader != NULL);
543   TestHelper::SetShaderStates(gl_.get(), vshader, true);
544   Shader* fshader = shader_manager_.CreateShader(
545       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
546   ASSERT_TRUE(fshader != NULL);
547   TestHelper::SetShaderStates(gl_.get(), fshader, true);
548   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
549   EXPECT_FALSE(program->CanLink());
550   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
551   EXPECT_TRUE(program->CanLink());
552   program->DetachShader(&shader_manager_, vshader);
553   EXPECT_FALSE(program->CanLink());
554   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
555   EXPECT_TRUE(program->CanLink());
556   program->DetachShader(&shader_manager_, fshader);
557   EXPECT_FALSE(program->CanLink());
558   EXPECT_FALSE(program->AttachShader(&shader_manager_, vshader));
559   EXPECT_FALSE(program->CanLink());
560   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
561   EXPECT_TRUE(program->CanLink());
562   TestHelper::SetShaderStates(gl_.get(), vshader, false);
563   EXPECT_FALSE(program->CanLink());
564   TestHelper::SetShaderStates(gl_.get(), vshader, true);
565   EXPECT_TRUE(program->CanLink());
566   TestHelper::SetShaderStates(gl_.get(), fshader, false);
567   EXPECT_FALSE(program->CanLink());
568   TestHelper::SetShaderStates(gl_.get(), fshader, true);
569   EXPECT_TRUE(program->CanLink());
570   EXPECT_TRUE(program->DetachShader(&shader_manager_, fshader));
571   EXPECT_FALSE(program->DetachShader(&shader_manager_, fshader));
572 }
573
574 TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) {
575   const Program* program = manager_.GetProgram(kClientProgramId);
576   ASSERT_TRUE(program != NULL);
577   // Emulate the situation that uniform3[1] isn't used and optimized out by
578   // a driver, so it's location is -1.
579   Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
580       program->GetUniformInfo(2));
581   ASSERT_TRUE(uniform != NULL && kUniform3Size == 2);
582   EXPECT_EQ(kUniform3Size, uniform->size);
583   uniform->element_locations[1] = -1;
584   EXPECT_EQ(kUniform1FakeLocation,
585             program->GetUniformFakeLocation(kUniform1Name));
586   EXPECT_EQ(kUniform2FakeLocation,
587             program->GetUniformFakeLocation(kUniform2Name));
588   EXPECT_EQ(kUniform3FakeLocation,
589             program->GetUniformFakeLocation(kUniform3BadName));
590   // Check we can get uniform2 as "uniform2" even though the name is
591   // "uniform2[0]"
592   EXPECT_EQ(kUniform2FakeLocation,
593             program->GetUniformFakeLocation("uniform2"));
594   // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
595   // returning "uniform3"
596   EXPECT_EQ(kUniform3FakeLocation,
597             program->GetUniformFakeLocation(kUniform3GoodName));
598   // Check that we can get the locations of the array elements > 1
599   EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 1),
600             program->GetUniformFakeLocation("uniform2[1]"));
601   EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2),
602             program->GetUniformFakeLocation("uniform2[2]"));
603   EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]"));
604   EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[1]"));
605   EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]"));
606 }
607
608 TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) {
609   const GLint kInvalidLocation = 1234;
610   const Program::UniformInfo* info;
611   const Program* program = manager_.GetProgram(kClientProgramId);
612   GLint real_location = -1;
613   GLint array_index = -1;
614   ASSERT_TRUE(program != NULL);
615   info = program->GetUniformInfoByFakeLocation(
616       kUniform2FakeLocation, &real_location, &array_index);
617   EXPECT_EQ(kUniform2RealLocation, real_location);
618   EXPECT_EQ(0, array_index);
619   ASSERT_TRUE(info != NULL);
620   EXPECT_EQ(kUniform2Type, info->type);
621   real_location = -1;
622   array_index = -1;
623   info = program->GetUniformInfoByFakeLocation(
624       kInvalidLocation, &real_location, &array_index);
625   EXPECT_TRUE(info == NULL);
626   EXPECT_EQ(-1, real_location);
627   EXPECT_EQ(-1, array_index);
628   GLint loc = program->GetUniformFakeLocation("uniform2[2]");
629   info = program->GetUniformInfoByFakeLocation(
630       loc, &real_location, &array_index);
631   ASSERT_TRUE(info != NULL);
632   EXPECT_EQ(kUniform2RealLocation + 2 * 2, real_location);
633   EXPECT_EQ(2, array_index);
634 }
635
636 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
637 // that start with "gl_". Our implementation catches these and does not allow
638 // them back to client.
639 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
640   static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
641   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
642     { kUniform1Name,
643       kUniform1Size,
644       kUniform1Type,
645       kUniform1FakeLocation,
646       kUniform1RealLocation,
647       kUniform1DesiredLocation,
648       kUniform1Name,
649     },
650     { kUniform2Name,
651       kUniform2Size,
652       kUniform2Type,
653       kUniform2FakeLocation,
654       kUniform2RealLocation,
655       kUniform2DesiredLocation,
656       kUniform2Name,
657     },
658     { kUniform3BadName,
659       kUniform3Size,
660       kUniform3Type,
661       kUniform3FakeLocation,
662       kUniform3RealLocation,
663       kUniform3DesiredLocation,
664       kUniform3GoodName,
665     },
666   };
667   const size_t kNumUniforms = arraysize(kUniforms);
668   static const GLuint kClientProgramId = 1234;
669   static const GLuint kServiceProgramId = 5679;
670   const GLuint kVShaderClientId = 2001;
671   const GLuint kFShaderClientId = 2002;
672   const GLuint kVShaderServiceId = 3001;
673   const GLuint kFShaderServiceId = 3002;
674   SetupShader(
675       kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
676   Shader* vshader = shader_manager_.CreateShader(
677       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
678   ASSERT_TRUE(vshader != NULL);
679   TestHelper::SetShaderStates(gl_.get(), vshader, true);
680   Shader* fshader = shader_manager_.CreateShader(
681       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
682   ASSERT_TRUE(fshader != NULL);
683   TestHelper::SetShaderStates(gl_.get(), fshader, true);
684   Program* program =
685       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
686   ASSERT_TRUE(program != NULL);
687   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
688   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
689   program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
690                 base::Bind(&ShaderCacheCb));
691   GLint value = 0;
692   program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
693   EXPECT_EQ(3, value);
694   // Check that we skipped the "gl_" uniform.
695   program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
696   EXPECT_EQ(2, value);
697   // Check that our max length adds room for the array spec and is not as long
698   // as the "gl_" uniform we skipped.
699   // +4u is to account for "gl_" and NULL terminator.
700   program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
701   EXPECT_EQ(strlen(kUniform3BadName) + 4u, static_cast<size_t>(value));
702 }
703
704 // Test the bug comparing similar array names is fixed.
705 TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
706   static const char* kUniform2Name = "u_nameLong[0]";
707   static const char* kUniform3Name = "u_name[0]";
708   static const GLint kUniform2Size = 2;
709   static const GLint kUniform3Size = 2;
710   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
711     { kUniform1Name,
712       kUniform1Size,
713       kUniform1Type,
714       kUniform1FakeLocation,
715       kUniform1RealLocation,
716       kUniform1DesiredLocation,
717       kUniform1Name,
718     },
719     { kUniform2Name,
720       kUniform2Size,
721       kUniform2Type,
722       kUniform2FakeLocation,
723       kUniform2RealLocation,
724       kUniform2DesiredLocation,
725       kUniform2Name,
726     },
727     { kUniform3Name,
728       kUniform3Size,
729       kUniform3Type,
730       kUniform3FakeLocation,
731       kUniform3RealLocation,
732       kUniform3DesiredLocation,
733       kUniform3Name,
734     },
735   };
736   const size_t kNumUniforms = arraysize(kUniforms);
737   static const GLuint kClientProgramId = 1234;
738   static const GLuint kServiceProgramId = 5679;
739   const GLuint kVShaderClientId = 2001;
740   const GLuint kFShaderClientId = 2002;
741   const GLuint kVShaderServiceId = 3001;
742   const GLuint kFShaderServiceId = 3002;
743   SetupShader(
744       kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
745   Shader* vshader = shader_manager_.CreateShader(
746       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
747   ASSERT_TRUE(vshader != NULL);
748   TestHelper::SetShaderStates(gl_.get(), vshader, true);
749   Shader* fshader = shader_manager_.CreateShader(
750       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
751   ASSERT_TRUE(fshader != NULL);
752   TestHelper::SetShaderStates(gl_.get(), fshader, true);
753   Program* program =
754       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
755   ASSERT_TRUE(program != NULL);
756   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
757   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
758   program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
759                 base::Bind(&ShaderCacheCb));
760
761   // Check that we get the correct locations.
762   EXPECT_EQ(kUniform2FakeLocation,
763             program->GetUniformFakeLocation(kUniform2Name));
764   EXPECT_EQ(kUniform3FakeLocation,
765             program->GetUniformFakeLocation(kUniform3Name));
766 }
767
768 // Some GL drivers incorrectly return the wrong type. For example they return
769 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
770 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
771   static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
772   static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
773   static GLenum kUniform2BadType = GL_FLOAT_VEC3;
774   static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
775   ShaderTranslator::VariableMap attrib_map;
776   ShaderTranslator::VariableMap uniform_map;
777   ShaderTranslator::VariableMap varying_map;
778   attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
779       kAttrib1Type, kAttrib1Size, kAttrib1Precision,
780       kAttribStaticUse, kAttrib1Name);
781   attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
782       kAttrib2GoodType, kAttrib2Size, kAttrib2Precision,
783       kAttribStaticUse, kAttrib2Name);
784   attrib_map[kAttrib3Name] = ShaderTranslatorInterface::VariableInfo(
785       kAttrib3Type, kAttrib3Size, kAttrib3Precision,
786       kAttribStaticUse, kAttrib3Name);
787   uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
788       kUniform1Type, kUniform1Size, kUniform1Precision,
789       kUniform1StaticUse, kUniform1Name);
790   uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
791       kUniform2GoodType, kUniform2Size, kUniform2Precision,
792       kUniform2StaticUse, kUniform2Name);
793   uniform_map[kUniform3GoodName] = ShaderTranslatorInterface::VariableInfo(
794       kUniform3Type, kUniform3Size, kUniform3Precision,
795       kUniform3StaticUse, kUniform3GoodName);
796   const GLuint kVShaderClientId = 2001;
797   const GLuint kFShaderClientId = 2002;
798   const GLuint kVShaderServiceId = 3001;
799   const GLuint kFShaderServiceId = 3002;
800   Shader* vshader = shader_manager_.CreateShader(
801       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
802   ASSERT_TRUE(vshader != NULL);
803   TestHelper::SetShaderStates(
804       gl_.get(), vshader, true, NULL, NULL,
805       &attrib_map, &uniform_map, &varying_map, NULL);
806   Shader* fshader = shader_manager_.CreateShader(
807       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
808   ASSERT_TRUE(fshader != NULL);
809   TestHelper::SetShaderStates(
810       gl_.get(), fshader, true, NULL, NULL,
811       &attrib_map, &uniform_map, &varying_map, NULL);
812   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
813     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
814     { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
815     { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
816   };
817   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
818     { kUniform1Name,
819       kUniform1Size,
820       kUniform1Type,
821       kUniform1FakeLocation,
822       kUniform1RealLocation,
823       kUniform1DesiredLocation,
824       kUniform1Name,
825     },
826     { kUniform2Name,
827       kUniform2Size,
828       kUniform2BadType,
829       kUniform2FakeLocation,
830       kUniform2RealLocation,
831       kUniform2DesiredLocation,
832       kUniform2Name,
833     },
834     { kUniform3BadName,
835       kUniform3Size,
836       kUniform3Type,
837       kUniform3FakeLocation,
838       kUniform3RealLocation,
839       kUniform3DesiredLocation,
840       kUniform3GoodName,
841     },
842   };
843   const size_t kNumAttribs= arraysize(kAttribs);
844   const size_t kNumUniforms = arraysize(kUniforms);
845   static const GLuint kClientProgramId = 1234;
846   static const GLuint kServiceProgramId = 5679;
847   SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
848               kServiceProgramId);
849   Program* program = manager_.CreateProgram(
850       kClientProgramId, kServiceProgramId);
851   ASSERT_TRUE(program!= NULL);
852   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
853   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
854   program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
855                 base::Bind(&ShaderCacheCb));
856   // Check that we got the good type, not the bad.
857   // Check Attribs
858   for (unsigned index = 0; index < kNumAttribs; ++index) {
859     const Program::VertexAttrib* attrib_info =
860         program->GetAttribInfo(index);
861     ASSERT_TRUE(attrib_info != NULL);
862     ShaderTranslator::VariableMap::const_iterator it = attrib_map.find(
863         attrib_info->name);
864     ASSERT_TRUE(it != attrib_map.end());
865     EXPECT_EQ(it->first, attrib_info->name);
866     EXPECT_EQ(static_cast<GLenum>(it->second.type), attrib_info->type);
867     EXPECT_EQ(it->second.size, attrib_info->size);
868     EXPECT_EQ(it->second.name, attrib_info->name);
869   }
870   // Check Uniforms
871   for (unsigned index = 0; index < kNumUniforms; ++index) {
872     const Program::UniformInfo* uniform_info =
873         program->GetUniformInfo(index);
874     ASSERT_TRUE(uniform_info != NULL);
875     ShaderTranslator::VariableMap::const_iterator it = uniform_map.find(
876         uniform_info->name);
877     ASSERT_TRUE(it != uniform_map.end());
878     EXPECT_EQ(it->first, uniform_info->name);
879     EXPECT_EQ(static_cast<GLenum>(it->second.type), uniform_info->type);
880     EXPECT_EQ(it->second.size, uniform_info->size);
881     EXPECT_EQ(it->second.name, uniform_info->name);
882   }
883 }
884
885 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
886   static const GLuint kClientProgramId = 124;
887   static const GLuint kServiceProgramId = 457;
888   Program* program = manager_.CreateProgram(
889       kClientProgramId, kServiceProgramId);
890   ASSERT_TRUE(program != NULL);
891   EXPECT_FALSE(program->CanLink());
892   const GLuint kVShaderClientId = 2001;
893   const GLuint kFShaderClientId = 2002;
894   const GLuint kVShaderServiceId = 3001;
895   const GLuint kFShaderServiceId = 3002;
896   Shader* vshader = shader_manager_.CreateShader(
897       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
898   ASSERT_TRUE(vshader != NULL);
899   TestHelper::SetShaderStates(gl_.get(), vshader, true);
900   Shader* fshader = shader_manager_.CreateShader(
901       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
902   ASSERT_TRUE(fshader != NULL);
903   TestHelper::SetShaderStates(gl_.get(), fshader, true);
904   EXPECT_FALSE(vshader->InUse());
905   EXPECT_FALSE(fshader->InUse());
906   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
907   EXPECT_TRUE(vshader->InUse());
908   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
909   EXPECT_TRUE(fshader->InUse());
910   EXPECT_TRUE(program->CanLink());
911   EXPECT_FALSE(program->InUse());
912   EXPECT_FALSE(program->IsDeleted());
913   manager_.UseProgram(program);
914   EXPECT_TRUE(program->InUse());
915   manager_.UseProgram(program);
916   EXPECT_TRUE(program->InUse());
917   manager_.MarkAsDeleted(&shader_manager_, program);
918   EXPECT_TRUE(program->IsDeleted());
919   Program* info2 = manager_.GetProgram(kClientProgramId);
920   EXPECT_EQ(program, info2);
921   manager_.UnuseProgram(&shader_manager_, program);
922   EXPECT_TRUE(program->InUse());
923   // this should delete the info.
924   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
925       .Times(1)
926       .RetiresOnSaturation();
927   manager_.UnuseProgram(&shader_manager_, program);
928   info2 = manager_.GetProgram(kClientProgramId);
929   EXPECT_TRUE(info2 == NULL);
930   EXPECT_FALSE(vshader->InUse());
931   EXPECT_FALSE(fshader->InUse());
932 }
933
934 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
935   static const GLuint kClientProgramId = 124;
936   static const GLuint kServiceProgramId = 457;
937   Program* program = manager_.CreateProgram(
938       kClientProgramId, kServiceProgramId);
939   ASSERT_TRUE(program != NULL);
940   EXPECT_FALSE(program->CanLink());
941   const GLuint kVShaderClientId = 2001;
942   const GLuint kFShaderClientId = 2002;
943   const GLuint kVShaderServiceId = 3001;
944   const GLuint kFShaderServiceId = 3002;
945   Shader* vshader = shader_manager_.CreateShader(
946       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
947   ASSERT_TRUE(vshader != NULL);
948   TestHelper::SetShaderStates(gl_.get(), vshader, true);
949   Shader* fshader = shader_manager_.CreateShader(
950       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
951   ASSERT_TRUE(fshader != NULL);
952   TestHelper::SetShaderStates(gl_.get(), fshader, true);
953   EXPECT_FALSE(vshader->InUse());
954   EXPECT_FALSE(fshader->InUse());
955   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
956   EXPECT_TRUE(vshader->InUse());
957   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
958   EXPECT_TRUE(fshader->InUse());
959   EXPECT_TRUE(program->CanLink());
960   EXPECT_FALSE(program->InUse());
961   EXPECT_FALSE(program->IsDeleted());
962   manager_.UseProgram(program);
963   EXPECT_TRUE(program->InUse());
964   manager_.UseProgram(program);
965   EXPECT_TRUE(program->InUse());
966   manager_.UnuseProgram(&shader_manager_, program);
967   EXPECT_TRUE(program->InUse());
968   manager_.UnuseProgram(&shader_manager_, program);
969   EXPECT_FALSE(program->InUse());
970   Program* info2 = manager_.GetProgram(kClientProgramId);
971   EXPECT_EQ(program, info2);
972   // this should delete the program.
973   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
974       .Times(1)
975       .RetiresOnSaturation();
976   manager_.MarkAsDeleted(&shader_manager_, program);
977   info2 = manager_.GetProgram(kClientProgramId);
978   EXPECT_TRUE(info2 == NULL);
979   EXPECT_FALSE(vshader->InUse());
980   EXPECT_FALSE(fshader->InUse());
981 }
982
983 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
984   CommonDecoder::Bucket bucket;
985   const Program* program = manager_.GetProgram(kClientProgramId);
986   ASSERT_TRUE(program != NULL);
987   program->GetProgramInfo(&manager_, &bucket);
988   ProgramInfoHeader* header =
989       bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
990   ASSERT_TRUE(header != NULL);
991   EXPECT_EQ(1u, header->link_status);
992   EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
993   EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
994   const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
995       sizeof(*header),
996       sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
997   ASSERT_TRUE(inputs != NULL);
998   const ProgramInput* input = inputs;
999   // TODO(gman): Don't assume these are in order.
1000   for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
1001     const AttribInfo& expected = kAttribs[ii];
1002     EXPECT_EQ(expected.size, input->size);
1003     EXPECT_EQ(expected.type, input->type);
1004     const int32* location = bucket.GetDataAs<const int32*>(
1005         input->location_offset, sizeof(int32));
1006     ASSERT_TRUE(location != NULL);
1007     EXPECT_EQ(expected.location, *location);
1008     const char* name_buf = bucket.GetDataAs<const char*>(
1009         input->name_offset, input->name_length);
1010     ASSERT_TRUE(name_buf != NULL);
1011     std::string name(name_buf, input->name_length);
1012     EXPECT_STREQ(expected.name, name.c_str());
1013     ++input;
1014   }
1015   // TODO(gman): Don't assume these are in order.
1016   for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1017     const UniformInfo& expected = kUniforms[ii];
1018     EXPECT_EQ(expected.size, input->size);
1019     EXPECT_EQ(expected.type, input->type);
1020     const int32* locations = bucket.GetDataAs<const int32*>(
1021         input->location_offset, sizeof(int32) * input->size);
1022     ASSERT_TRUE(locations != NULL);
1023     for (int32 jj = 0; jj < input->size; ++jj) {
1024       EXPECT_EQ(
1025           ProgramManager::MakeFakeLocation(expected.fake_location, jj),
1026           locations[jj]);
1027     }
1028     const char* name_buf = bucket.GetDataAs<const char*>(
1029         input->name_offset, input->name_length);
1030     ASSERT_TRUE(name_buf != NULL);
1031     std::string name(name_buf, input->name_length);
1032     EXPECT_STREQ(expected.good_name, name.c_str());
1033     ++input;
1034   }
1035   EXPECT_EQ(header->num_attribs + header->num_uniforms,
1036             static_cast<uint32>(input - inputs));
1037 }
1038
1039 // Some drivers optimize out unused uniform array elements, so their
1040 // location would be -1.
1041 TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
1042   CommonDecoder::Bucket bucket;
1043   const Program* program = manager_.GetProgram(kClientProgramId);
1044   ASSERT_TRUE(program != NULL);
1045   // Emulate the situation that only the first element has a valid location.
1046   // TODO(zmo): Don't assume these are in order.
1047   for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
1048     Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
1049         program->GetUniformInfo(ii));
1050     ASSERT_TRUE(uniform != NULL);
1051     EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
1052               uniform->element_locations.size());
1053     for (GLsizei jj = 1; jj < uniform->size; ++jj)
1054       uniform->element_locations[jj] = -1;
1055   }
1056   program->GetProgramInfo(&manager_, &bucket);
1057   ProgramInfoHeader* header =
1058       bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
1059   ASSERT_TRUE(header != NULL);
1060   EXPECT_EQ(1u, header->link_status);
1061   EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
1062   EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
1063   const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
1064       sizeof(*header),
1065       sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
1066   ASSERT_TRUE(inputs != NULL);
1067   const ProgramInput* input = inputs + header->num_attribs;
1068   for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
1069     const UniformInfo& expected = kUniforms[ii];
1070     EXPECT_EQ(expected.size, input->size);
1071     const int32* locations = bucket.GetDataAs<const int32*>(
1072         input->location_offset, sizeof(int32) * input->size);
1073     ASSERT_TRUE(locations != NULL);
1074     EXPECT_EQ(
1075         ProgramManager::MakeFakeLocation(expected.fake_location, 0),
1076         locations[0]);
1077     for (int32 jj = 1; jj < input->size; ++jj)
1078       EXPECT_EQ(-1, locations[jj]);
1079     ++input;
1080   }
1081 }
1082
1083 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
1084   // Set up shader
1085   const GLuint kVShaderClientId = 1;
1086   const GLuint kVShaderServiceId = 11;
1087   const GLuint kFShaderClientId = 2;
1088   const GLuint kFShaderServiceId = 12;
1089   ShaderTranslator::VariableMap attrib_map;
1090   for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
1091     attrib_map[kAttribs[ii].name] = ShaderTranslatorInterface::VariableInfo(
1092         kAttribs[ii].type,
1093         kAttribs[ii].size,
1094         SH_PRECISION_MEDIUMP,
1095         kAttribStaticUse,
1096         kAttribs[ii].name);
1097   }
1098   // Check we can create shader.
1099   Shader* vshader = shader_manager_.CreateShader(
1100       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1101   Shader* fshader = shader_manager_.CreateShader(
1102       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1103   // Check shader got created.
1104   ASSERT_TRUE(vshader != NULL && fshader != NULL);
1105   // Set Status
1106   TestHelper::SetShaderStates(
1107       gl_.get(), vshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1108   // Check attrib infos got copied.
1109   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
1110        it != attrib_map.end(); ++it) {
1111     const Shader::VariableInfo* variable_info =
1112         vshader->GetAttribInfo(it->first);
1113     ASSERT_TRUE(variable_info != NULL);
1114     EXPECT_EQ(it->second.type, variable_info->type);
1115     EXPECT_EQ(it->second.size, variable_info->size);
1116     EXPECT_EQ(it->second.precision, variable_info->precision);
1117     EXPECT_EQ(it->second.static_use, variable_info->static_use);
1118     EXPECT_EQ(it->second.name, variable_info->name);
1119   }
1120   TestHelper::SetShaderStates(
1121       gl_.get(), fshader, true, NULL, NULL, &attrib_map, NULL, NULL, NULL);
1122
1123   // Set up program
1124   const GLuint kClientProgramId = 6666;
1125   const GLuint kServiceProgramId = 8888;
1126   Program* program =
1127       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1128   ASSERT_TRUE(program != NULL);
1129   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1130   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1131
1132   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1133   EXPECT_TRUE(LinkAsExpected(program, true));
1134
1135   program->SetAttribLocationBinding(kAttrib1Name, 0);
1136   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1137   EXPECT_TRUE(LinkAsExpected(program, true));
1138
1139   program->SetAttribLocationBinding("xxx", 0);
1140   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1141   EXPECT_TRUE(LinkAsExpected(program, true));
1142
1143   program->SetAttribLocationBinding(kAttrib2Name, 1);
1144   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1145   EXPECT_TRUE(LinkAsExpected(program, true));
1146
1147   program->SetAttribLocationBinding(kAttrib2Name, 0);
1148   EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1149   EXPECT_TRUE(LinkAsExpected(program, false));
1150 }
1151
1152 TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
1153   // Set up shader
1154   const GLuint kVShaderClientId = 1;
1155   const GLuint kVShaderServiceId = 11;
1156   const GLuint kFShaderClientId = 2;
1157   const GLuint kFShaderServiceId = 12;
1158
1159   ShaderTranslator::VariableMap vertex_uniform_map;
1160   vertex_uniform_map["a"] = ShaderTranslator::VariableInfo(
1161       1, 3, SH_PRECISION_MEDIUMP, 1, "a");
1162   ShaderTranslator::VariableMap frag_uniform_map;
1163   frag_uniform_map["a"] = ShaderTranslator::VariableInfo(
1164       1, 3, SH_PRECISION_LOWP, 1, "a");
1165
1166   // Check we can create shader.
1167   Shader* vshader = shader_manager_.CreateShader(
1168       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1169   Shader* fshader = shader_manager_.CreateShader(
1170       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1171   // Check shader got created.
1172   ASSERT_TRUE(vshader != NULL && fshader != NULL);
1173   // Set Status
1174   TestHelper::SetShaderStates(
1175       gl_.get(), vshader, true, NULL, NULL, NULL,
1176       &vertex_uniform_map, NULL, NULL);
1177   TestHelper::SetShaderStates(
1178       gl_.get(), fshader, true, NULL, NULL, NULL,
1179       &frag_uniform_map, NULL, NULL);
1180
1181   // Set up program
1182   const GLuint kClientProgramId = 6666;
1183   const GLuint kServiceProgramId = 8888;
1184   Program* program =
1185       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
1186   ASSERT_TRUE(program != NULL);
1187   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1188   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1189
1190   std::string conflicting_name;
1191
1192   EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1193   EXPECT_EQ("a", conflicting_name);
1194   EXPECT_TRUE(LinkAsExpected(program, false));
1195 }
1196
1197 // If a varying has different type in the vertex and fragment
1198 // shader, linking should fail.
1199 TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
1200   const VarInfo kVertexVarying =
1201       { GL_FLOAT_VEC3, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1202   const VarInfo kFragmentVarying =
1203       { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1204   Program* program = SetupShaderVariableTest(
1205       &kVertexVarying, 1, &kFragmentVarying, 1);
1206
1207   std::string conflicting_name;
1208
1209   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1210   EXPECT_EQ("a", conflicting_name);
1211   EXPECT_TRUE(LinkAsExpected(program, false));
1212 }
1213
1214 // If a varying has different array size in the vertex and fragment
1215 // shader, linking should fail.
1216 TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
1217   const VarInfo kVertexVarying =
1218       { GL_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1219   const VarInfo kFragmentVarying =
1220       { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1221   Program* program = SetupShaderVariableTest(
1222       &kVertexVarying, 1, &kFragmentVarying, 1);
1223
1224   std::string conflicting_name;
1225
1226   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1227   EXPECT_EQ("a", conflicting_name);
1228   EXPECT_TRUE(LinkAsExpected(program, false));
1229 }
1230
1231 // If a varying has different precision in the vertex and fragment
1232 // shader, linking should succeed.
1233 TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
1234   const VarInfo kVertexVarying =
1235       { GL_FLOAT, 2, SH_PRECISION_HIGHP, 1, "a", kVarVarying };
1236   const VarInfo kFragmentVarying =
1237       { GL_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1238   Program* program = SetupShaderVariableTest(
1239       &kVertexVarying, 1, &kFragmentVarying, 1);
1240
1241   std::string conflicting_name;
1242
1243   EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1244   EXPECT_TRUE(conflicting_name.empty());
1245   EXPECT_TRUE(LinkAsExpected(program, true));
1246 }
1247
1248 // If a varying is statically used in fragment shader but not
1249 // declared in vertex shader, link should fail.
1250 TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
1251   const VarInfo kFragmentVarying =
1252       { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
1253   Program* program = SetupShaderVariableTest(
1254       NULL, 0, &kFragmentVarying, 1);
1255
1256   std::string conflicting_name;
1257
1258   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1259   EXPECT_EQ("a", conflicting_name);
1260   EXPECT_TRUE(LinkAsExpected(program, false));
1261 }
1262
1263 // If a varying is declared but not statically used in fragment
1264 // shader, even if it's not declared in vertex shader, link should
1265 // succeed.
1266 TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
1267   const VarInfo kFragmentVarying =
1268       { GL_FLOAT, 3, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying };
1269   Program* program = SetupShaderVariableTest(
1270       NULL, 0, &kFragmentVarying, 1);
1271
1272   std::string conflicting_name;
1273
1274   EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1275   EXPECT_TRUE(conflicting_name.empty());
1276   EXPECT_TRUE(LinkAsExpected(program, true));
1277 }
1278
1279 // Uniforms and attributes are both global variables, thus sharing
1280 // the same namespace. Any name conflicts should cause link
1281 // failure.
1282 TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
1283   const VarInfo kVertexAttribute =
1284       { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarAttribute };
1285   const VarInfo kFragmentUniform =
1286       { GL_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarUniform };
1287   Program* program = SetupShaderVariableTest(
1288       &kVertexAttribute, 1, &kFragmentUniform, 1);
1289
1290   std::string conflicting_name;
1291
1292   EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1293   EXPECT_EQ("a", conflicting_name);
1294   EXPECT_TRUE(LinkAsExpected(program, false));
1295 }
1296
1297 // Varyings go over 8 rows.
1298 TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
1299   const VarInfo kVertexVaryings[] = {
1300       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1301       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1302   };
1303   const VarInfo kFragmentVaryings[] = {
1304       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1305       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1306   };
1307   Program* program = SetupShaderVariableTest(
1308       kVertexVaryings, 2, kFragmentVaryings, 2);
1309
1310   EXPECT_FALSE(
1311       program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1312   EXPECT_TRUE(LinkAsExpected(program, false));
1313 }
1314
1315 // Varyings go over 8 rows but some are inactive
1316 TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
1317   const VarInfo kVertexVaryings[] = {
1318       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1319       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1320   };
1321   const VarInfo kFragmentVaryings[] = {
1322       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
1323       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1324   };
1325   Program* program = SetupShaderVariableTest(
1326       kVertexVaryings, 2, kFragmentVaryings, 2);
1327
1328   EXPECT_TRUE(
1329       program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1330   EXPECT_TRUE(LinkAsExpected(program, true));
1331 }
1332
1333 // Varyings go over 8 rows but some are inactive.
1334 // However, we still fail the check if kCountAll option is used.
1335 TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
1336   const VarInfo kVertexVaryings[] = {
1337       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
1338       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1339   };
1340   const VarInfo kFragmentVaryings[] = {
1341       { GL_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
1342       { GL_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
1343   };
1344   Program* program = SetupShaderVariableTest(
1345       kVertexVaryings, 2, kFragmentVaryings, 2);
1346
1347   EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1348 }
1349
1350 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
1351   const GLuint kVShaderClientId = 2001;
1352   const GLuint kFShaderClientId = 2002;
1353   const GLuint kVShaderServiceId = 3001;
1354   const GLuint kFShaderServiceId = 3002;
1355   Shader* vshader = shader_manager_.CreateShader(
1356       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1357   ASSERT_TRUE(vshader != NULL);
1358   TestHelper::SetShaderStates(gl_.get(), vshader, true);
1359   Shader* fshader = shader_manager_.CreateShader(
1360       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1361   ASSERT_TRUE(fshader != NULL);
1362   TestHelper::SetShaderStates(gl_.get(), fshader, true);
1363   static const GLuint kClientProgramId = 1234;
1364   static const GLuint kServiceProgramId = 5679;
1365   Program* program = manager_.CreateProgram(
1366       kClientProgramId, kServiceProgramId);
1367   ASSERT_TRUE(program != NULL);
1368   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1369   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1370
1371   static const GLenum kSamplerTypes[] = {
1372     GL_SAMPLER_2D,
1373     GL_SAMPLER_CUBE,
1374     GL_SAMPLER_EXTERNAL_OES,
1375     GL_SAMPLER_3D_OES,
1376     GL_SAMPLER_2D_RECT_ARB,
1377   };
1378   const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
1379   for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
1380     static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1381       { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1382       { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1383       { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1384     };
1385     ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1386       { kUniform1Name,
1387         kUniform1Size,
1388         kUniform1Type,
1389         kUniform1FakeLocation,
1390         kUniform1RealLocation,
1391         kUniform1DesiredLocation,
1392         kUniform1Name,
1393       },
1394       { kUniform2Name,
1395         kUniform2Size,
1396         kSamplerTypes[ii],
1397         kUniform2FakeLocation,
1398         kUniform2RealLocation,
1399         kUniform2DesiredLocation,
1400         kUniform2Name,
1401       },
1402       { kUniform3BadName,
1403         kUniform3Size,
1404         kUniform3Type,
1405         kUniform3FakeLocation,
1406         kUniform3RealLocation,
1407         kUniform3DesiredLocation,
1408         kUniform3GoodName,
1409       },
1410     };
1411     const size_t kNumAttribs = arraysize(kAttribs);
1412     const size_t kNumUniforms = arraysize(kUniforms);
1413     SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1414                 kServiceProgramId);
1415     program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
1416                   base::Bind(&ShaderCacheCb));
1417     SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
1418     manager_.ClearUniforms(program);
1419   }
1420 }
1421
1422 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
1423   const GLuint kVShaderClientId = 2001;
1424   const GLuint kFShaderClientId = 2002;
1425   const GLuint kVShaderServiceId = 3001;
1426   const GLuint kFShaderServiceId = 3002;
1427
1428   const GLint kUniform1DesiredLocation = 10;
1429   const GLint kUniform2DesiredLocation = -1;
1430   const GLint kUniform3DesiredLocation = 5;
1431
1432   Shader* vshader = shader_manager_.CreateShader(
1433       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
1434   ASSERT_TRUE(vshader != NULL);
1435   TestHelper::SetShaderStates(gl_.get(), vshader, true);
1436   Shader* fshader = shader_manager_.CreateShader(
1437       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
1438   ASSERT_TRUE(fshader != NULL);
1439   TestHelper::SetShaderStates(gl_.get(), fshader, true);
1440   static const GLuint kClientProgramId = 1234;
1441   static const GLuint kServiceProgramId = 5679;
1442   Program* program = manager_.CreateProgram(
1443       kClientProgramId, kServiceProgramId);
1444   ASSERT_TRUE(program != NULL);
1445   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
1446   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
1447   EXPECT_TRUE(program->SetUniformLocationBinding(
1448       kUniform1Name, kUniform1DesiredLocation));
1449   EXPECT_TRUE(program->SetUniformLocationBinding(
1450       kUniform3BadName, kUniform3DesiredLocation));
1451
1452   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1453     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1454     { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1455     { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1456   };
1457   ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1458     { kUniform1Name,
1459       kUniform1Size,
1460       kUniform1Type,
1461       kUniform1FakeLocation,
1462       kUniform1RealLocation,
1463       kUniform1DesiredLocation,
1464       kUniform1Name,
1465     },
1466     { kUniform2Name,
1467       kUniform2Size,
1468       kUniform2Type,
1469       kUniform2FakeLocation,
1470       kUniform2RealLocation,
1471       kUniform2DesiredLocation,
1472       kUniform2Name,
1473     },
1474     { kUniform3BadName,
1475       kUniform3Size,
1476       kUniform3Type,
1477       kUniform3FakeLocation,
1478       kUniform3RealLocation,
1479       kUniform3DesiredLocation,
1480       kUniform3GoodName,
1481     },
1482   };
1483
1484   const size_t kNumAttribs = arraysize(kAttribs);
1485   const size_t kNumUniforms = arraysize(kUniforms);
1486   SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
1487               kServiceProgramId);
1488   program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
1489                 base::Bind(&ShaderCacheCb));
1490
1491   EXPECT_EQ(kUniform1DesiredLocation,
1492             program->GetUniformFakeLocation(kUniform1Name));
1493   EXPECT_EQ(kUniform3DesiredLocation,
1494             program->GetUniformFakeLocation(kUniform3BadName));
1495   EXPECT_EQ(kUniform3DesiredLocation,
1496             program->GetUniformFakeLocation(kUniform3GoodName));
1497 }
1498
1499 class ProgramManagerWithCacheTest : public GpuServiceTest {
1500  public:
1501   static const GLuint kClientProgramId = 1;
1502   static const GLuint kServiceProgramId = 10;
1503   static const GLuint kVertexShaderClientId = 2;
1504   static const GLuint kFragmentShaderClientId = 20;
1505   static const GLuint kVertexShaderServiceId = 3;
1506   static const GLuint kFragmentShaderServiceId = 30;
1507
1508   ProgramManagerWithCacheTest()
1509       : cache_(new MockProgramCache()),
1510         manager_(cache_.get(), kMaxVaryingVectors),
1511         vertex_shader_(NULL),
1512         fragment_shader_(NULL),
1513         program_(NULL) {
1514   }
1515   virtual ~ProgramManagerWithCacheTest() {
1516     manager_.Destroy(false);
1517     shader_manager_.Destroy(false);
1518   }
1519
1520  protected:
1521   virtual void SetUp() {
1522     GpuServiceTest::SetUp();
1523
1524     vertex_shader_ = shader_manager_.CreateShader(
1525        kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
1526     fragment_shader_ = shader_manager_.CreateShader(
1527        kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
1528     ASSERT_TRUE(vertex_shader_ != NULL);
1529     ASSERT_TRUE(fragment_shader_ != NULL);
1530     vertex_shader_->set_source("lka asjf bjajsdfj");
1531     fragment_shader_->set_source("lka asjf a   fasgag 3rdsf3 bjajsdfj");
1532
1533     program_ = manager_.CreateProgram(
1534         kClientProgramId, kServiceProgramId);
1535     ASSERT_TRUE(program_ != NULL);
1536
1537     program_->AttachShader(&shader_manager_, vertex_shader_);
1538     program_->AttachShader(&shader_manager_, fragment_shader_);
1539   }
1540
1541   void SetShadersCompiled() {
1542     TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
1543     TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
1544   }
1545
1546   void SetProgramCached() {
1547     cache_->LinkedProgramCacheSuccess(
1548         vertex_shader_->source(),
1549         NULL,
1550         fragment_shader_->source(),
1551         NULL,
1552         &program_->bind_attrib_location_map());
1553   }
1554
1555   void SetExpectationsForProgramCached() {
1556     SetExpectationsForProgramCached(program_,
1557                                     vertex_shader_,
1558                                     fragment_shader_);
1559   }
1560
1561   void SetExpectationsForProgramCached(
1562       Program* program,
1563       Shader* vertex_shader,
1564       Shader* fragment_shader) {
1565     EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1566         program->service_id(),
1567         vertex_shader,
1568         NULL,
1569         fragment_shader,
1570         NULL,
1571         &program->bind_attrib_location_map(),
1572         _)).Times(1);
1573   }
1574
1575   void SetExpectationsForNotCachingProgram() {
1576     SetExpectationsForNotCachingProgram(program_,
1577                                         vertex_shader_,
1578                                         fragment_shader_);
1579   }
1580
1581   void SetExpectationsForNotCachingProgram(
1582       Program* program,
1583       Shader* vertex_shader,
1584       Shader* fragment_shader) {
1585     EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
1586         program->service_id(),
1587         vertex_shader,
1588         NULL,
1589         fragment_shader,
1590         NULL,
1591         &program->bind_attrib_location_map(),
1592         _)).Times(0);
1593   }
1594
1595   void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
1596     SetExpectationsForProgramLoad(kServiceProgramId,
1597                                   program_,
1598                                   vertex_shader_,
1599                                   fragment_shader_,
1600                                   result);
1601   }
1602
1603   void SetExpectationsForProgramLoad(
1604       GLuint service_program_id,
1605       Program* program,
1606       Shader* vertex_shader,
1607       Shader* fragment_shader,
1608       ProgramCache::ProgramLoadResult result) {
1609     EXPECT_CALL(*cache_.get(),
1610                 LoadLinkedProgram(service_program_id,
1611                                   vertex_shader,
1612                                   NULL,
1613                                   fragment_shader,
1614                                   NULL,
1615                                   &program->bind_attrib_location_map(),
1616                                   _))
1617         .WillOnce(Return(result));
1618   }
1619
1620   void SetExpectationsForProgramLoadSuccess() {
1621     SetExpectationsForProgramLoadSuccess(kServiceProgramId);
1622   }
1623
1624   void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
1625     TestHelper::SetupProgramSuccessExpectations(gl_.get(),
1626                                                 NULL,
1627                                                 0,
1628                                                 NULL,
1629                                                 0,
1630                                                 service_program_id);
1631   }
1632
1633   void SetExpectationsForProgramLink() {
1634     SetExpectationsForProgramLink(kServiceProgramId);
1635   }
1636
1637   void SetExpectationsForProgramLink(GLuint service_program_id) {
1638     TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
1639     if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
1640       EXPECT_CALL(*gl_.get(),
1641                   ProgramParameteri(service_program_id,
1642                                     PROGRAM_BINARY_RETRIEVABLE_HINT,
1643                                     GL_TRUE)).Times(1);
1644     }
1645   }
1646
1647   void SetExpectationsForSuccessCompile(
1648       const Shader* shader) {
1649     const GLuint shader_id = shader->service_id();
1650     const char* src = shader->source().c_str();
1651     EXPECT_CALL(*gl_.get(),
1652                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
1653     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
1654     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1655         .WillOnce(SetArgumentPointee<2>(GL_TRUE));
1656   }
1657
1658   void SetExpectationsForNoCompile(const Shader* shader) {
1659     const GLuint shader_id = shader->service_id();
1660     const char* src = shader->source().c_str();
1661     EXPECT_CALL(*gl_.get(),
1662                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
1663     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
1664     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1665         .Times(0);
1666   }
1667
1668   void SetExpectationsForErrorCompile(const Shader* shader) {
1669     const GLuint shader_id = shader->service_id();
1670     const char* src = shader->source().c_str();
1671     EXPECT_CALL(*gl_.get(),
1672                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
1673     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
1674     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
1675         .WillOnce(SetArgumentPointee<2>(GL_FALSE));
1676     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
1677         .WillOnce(SetArgumentPointee<2>(0));
1678     EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
1679         .Times(1);
1680   }
1681
1682   scoped_ptr<MockProgramCache> cache_;
1683   ProgramManager manager_;
1684
1685   Shader* vertex_shader_;
1686   Shader* fragment_shader_;
1687   Program* program_;
1688   ShaderManager shader_manager_;
1689 };
1690
1691 // GCC requires these declarations, but MSVC requires they not be present
1692 #ifndef COMPILER_MSVC
1693 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
1694 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
1695 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
1696 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
1697 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
1698 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
1699 #endif
1700
1701 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
1702   SetShadersCompiled();
1703   SetExpectationsForProgramLink();
1704   SetExpectationsForProgramCached();
1705   EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
1706       Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
1707 }
1708
1709 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
1710   SetShadersCompiled();
1711   SetProgramCached();
1712
1713   SetExpectationsForNoCompile(vertex_shader_);
1714   SetExpectationsForNoCompile(fragment_shader_);
1715   SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
1716   SetExpectationsForNotCachingProgram();
1717   SetExpectationsForProgramLoadSuccess();
1718
1719   EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
1720       Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
1721 }
1722
1723 }  // namespace gles2
1724 }  // namespace gpu