Upstream version 9.38.198.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 // 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
43
44 namespace gpu {
45 namespace gles2 {
46
47 namespace {
48 const uint32 kMaxVaryingVectors = 8;
49
50 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
51 }  // namespace anonymous
52
53 class ProgramManagerTest : public GpuServiceTest {
54  public:
55   ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
56   virtual ~ProgramManagerTest() {
57     manager_.Destroy(false);
58   }
59
60  protected:
61   ProgramManager manager_;
62 };
63
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);
78 }
79
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);
96 }
97
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()));
121 }
122
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);
136 }
137
138 class ProgramManagerWithShaderTest : public GpuServiceTest {
139  public:
140   ProgramManagerWithShaderTest()
141       :  manager_(NULL, kMaxVaryingVectors), program_(NULL) {
142   }
143
144   virtual ~ProgramManagerWithShaderTest() {
145     manager_.Destroy(false);
146     shader_manager_.Destroy(false);
147   }
148
149   static const GLint kNumVertexAttribs = 16;
150
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;
157
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;
176
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;
204
205   static const size_t kNumAttribs;
206   static const size_t kNumUniforms;
207
208  protected:
209   typedef TestHelper::AttribInfo AttribInfo;
210   typedef TestHelper::UniformInfo UniformInfo;
211
212   typedef enum {
213     kVarUniform,
214     kVarVarying,
215     kVarAttribute
216   } VarCategory;
217
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;
226
227   virtual void SetUp() {
228     GpuServiceTest::SetUp();
229
230     SetupDefaultShaderExpectations();
231
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);
242
243     program_ = manager_.CreateProgram(
244         kClientProgramId, kServiceProgramId);
245     ASSERT_TRUE(program_ != NULL);
246
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));
251   }
252
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);
258   }
259
260   void SetupDefaultShaderExpectations() {
261     SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
262                 kServiceProgramId);
263   }
264
265   void SetupExpectationsForClearingUniforms(
266       UniformInfo* uniforms, size_t num_uniforms) {
267     TestHelper::SetupExpectationsForClearingUniforms(
268         gl_.get(), uniforms, num_uniforms);
269   }
270
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);
278     }
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);
284   }
285
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;
295
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();
314       }
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);
321     }
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));
331
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();
350       }
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);
357     }
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));
367
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);
378
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;
388   }
389
390   static AttribInfo kAttribs[];
391   static UniformInfo kUniforms[];
392
393   ProgramManager manager_;
394   Program* program_;
395   ShaderManager shader_manager_;
396 };
397
398 ProgramManagerWithShaderTest::AttribInfo
399     ProgramManagerWithShaderTest::kAttribs[] = {
400   { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
401   { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
402   { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
403 };
404
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
443
444 const size_t ProgramManagerWithShaderTest::kNumAttribs =
445     arraysize(ProgramManagerWithShaderTest::kAttribs);
446
447 ProgramManagerWithShaderTest::UniformInfo
448     ProgramManagerWithShaderTest::kUniforms[] = {
449   { kUniform1Name,
450     kUniform1Size,
451     kUniform1Type,
452     kUniform1FakeLocation,
453     kUniform1RealLocation,
454     kUniform1DesiredLocation,
455     kUniform1Name,
456   },
457   { kUniform2Name,
458     kUniform2Size,
459     kUniform2Type,
460     kUniform2FakeLocation,
461     kUniform2RealLocation,
462     kUniform2DesiredLocation,
463     kUniform2Name,
464   },
465   { kUniform3BadName,
466     kUniform3Size,
467     kUniform3Type,
468     kUniform3FakeLocation,
469     kUniform3RealLocation,
470     kUniform3DesiredLocation,
471     kUniform3GoodName,
472   },
473 };
474
475 const size_t ProgramManagerWithShaderTest::kNumUniforms =
476     arraysize(ProgramManagerWithShaderTest::kUniforms);
477
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]";
487
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());
501   }
502 }
503
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);
517 }
518
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));
525 }
526
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);
553 }
554
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));
598 }
599
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]"));
632 }
633
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);
660 }
661
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,
675     },
676     { kUniform2Name,
677       kUniform2Size,
678       kUniform2Type,
679       kUniform2FakeLocation,
680       kUniform2RealLocation,
681       kUniform2DesiredLocation,
682       kUniform2Name,
683     },
684     { kUniform3BadName,
685       kUniform3Size,
686       kUniform3Type,
687       kUniform3FakeLocation,
688       kUniform3RealLocation,
689       kUniform3DesiredLocation,
690       kUniform3GoodName,
691     },
692   };
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));
728 }
729
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,
744     },
745     { kUniform2Name,
746       kUniform2Size,
747       kUniform2Type,
748       kUniform2FakeLocation,
749       kUniform2RealLocation,
750       kUniform2DesiredLocation,
751       kUniform2Name,
752     },
753     { kUniform3Name,
754       kUniform3Size,
755       kUniform3Type,
756       kUniform3FakeLocation,
757       kUniform3RealLocation,
758       kUniform3DesiredLocation,
759       kUniform3Name,
760     },
761   };
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));
786
787   // Check that we get the correct locations.
788   EXPECT_EQ(kUniform2FakeLocation,
789             program->GetUniformFakeLocation(kUniform2Name));
790   EXPECT_EQ(kUniform3FakeLocation,
791             program->GetUniformFakeLocation(kUniform3Name));
792 }
793
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, },
848   };
849   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
850     { kUniform1Name,
851       kUniform1Size,
852       kUniform1Type,
853       kUniform1FakeLocation,
854       kUniform1RealLocation,
855       kUniform1DesiredLocation,
856       kUniform1Name,
857     },
858     { kUniform2Name,
859       kUniform2Size,
860       kUniform2BadType,
861       kUniform2FakeLocation,
862       kUniform2RealLocation,
863       kUniform2DesiredLocation,
864       kUniform2Name,
865     },
866     { kUniform3BadName,
867       kUniform3Size,
868       kUniform3Type,
869       kUniform3FakeLocation,
870       kUniform3RealLocation,
871       kUniform3DesiredLocation,
872       kUniform3GoodName,
873     },
874   };
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);
901   }
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);
914   }
915 }
916
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());
964 }
965
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());
1013 }
1014
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;
1046   }
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]);
1059     }
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;
1066   }
1067   EXPECT_EQ(header->num_attribs + header->num_uniforms,
1068             static_cast<uint32>(input - inputs));
1069 }
1070
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;
1087   }
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;
1112   }
1113 }
1114
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);
1130   }
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);
1162   }
1163   fshader->SetStatus(true, "", NULL);
1164
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));
1173
1174   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1175   EXPECT_TRUE(LinkAsExpected(program, true));
1176
1177   program->SetAttribLocationBinding(kAttrib1Name, 0);
1178   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1179   EXPECT_TRUE(LinkAsExpected(program, true));
1180
1181   program->SetAttribLocationBinding("xxx", 0);
1182   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1183   EXPECT_TRUE(LinkAsExpected(program, true));
1184
1185   program->SetAttribLocationBinding(kAttrib2Name, 1);
1186   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
1187   EXPECT_TRUE(LinkAsExpected(program, true));
1188
1189   program->SetAttribLocationBinding(kAttrib2Name, 0);
1190   EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
1191   EXPECT_TRUE(LinkAsExpected(program, false));
1192 }
1193
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;
1200
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));
1216
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));
1232
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);
1243
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));
1252
1253   std::string conflicting_name;
1254
1255   EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
1256   EXPECT_EQ("a", conflicting_name);
1257   EXPECT_TRUE(LinkAsExpected(program, false));
1258 }
1259
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);
1269
1270   std::string conflicting_name;
1271
1272   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1273   EXPECT_EQ("a", conflicting_name);
1274   EXPECT_TRUE(LinkAsExpected(program, false));
1275 }
1276
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);
1286
1287   std::string conflicting_name;
1288
1289   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1290   EXPECT_EQ("a", conflicting_name);
1291   EXPECT_TRUE(LinkAsExpected(program, false));
1292 }
1293
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);
1303
1304   std::string conflicting_name;
1305
1306   EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1307   EXPECT_TRUE(conflicting_name.empty());
1308   EXPECT_TRUE(LinkAsExpected(program, true));
1309 }
1310
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);
1318
1319   std::string conflicting_name;
1320
1321   EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
1322   EXPECT_EQ("a", conflicting_name);
1323   EXPECT_TRUE(LinkAsExpected(program, false));
1324 }
1325
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);
1334
1335   std::string conflicting_name;
1336
1337   EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
1338   EXPECT_TRUE(conflicting_name.empty());
1339   EXPECT_TRUE(LinkAsExpected(program, true));
1340 }
1341
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);
1352
1353   std::string conflicting_name;
1354
1355   EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
1356   EXPECT_EQ("a", conflicting_name);
1357   EXPECT_TRUE(LinkAsExpected(program, false));
1358 }
1359
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 }
1365   };
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 }
1369   };
1370   Program* program = SetupShaderVariableTest(
1371       kVertexVaryings, 2, kFragmentVaryings, 2);
1372
1373   EXPECT_FALSE(
1374       program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1375   EXPECT_TRUE(LinkAsExpected(program, false));
1376 }
1377
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 }
1383   };
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 }
1387   };
1388   Program* program = SetupShaderVariableTest(
1389       kVertexVaryings, 2, kFragmentVaryings, 2);
1390
1391   EXPECT_TRUE(
1392       program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
1393   EXPECT_TRUE(LinkAsExpected(program, true));
1394 }
1395
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 }
1402   };
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 }
1406   };
1407   Program* program = SetupShaderVariableTest(
1408       kVertexVaryings, 2, kFragmentVaryings, 2);
1409
1410   EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
1411 }
1412
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));
1433
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,
1440   };
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, },
1447     };
1448     ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1449       { kUniform1Name,
1450         kUniform1Size,
1451         kUniform1Type,
1452         kUniform1FakeLocation,
1453         kUniform1RealLocation,
1454         kUniform1DesiredLocation,
1455         kUniform1Name,
1456       },
1457       { kUniform2Name,
1458         kUniform2Size,
1459         kSamplerTypes[ii],
1460         kUniform2FakeLocation,
1461         kUniform2RealLocation,
1462         kUniform2DesiredLocation,
1463         kUniform2Name,
1464       },
1465       { kUniform3BadName,
1466         kUniform3Size,
1467         kUniform3Type,
1468         kUniform3FakeLocation,
1469         kUniform3RealLocation,
1470         kUniform3DesiredLocation,
1471         kUniform3GoodName,
1472       },
1473     };
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);
1482   }
1483 }
1484
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;
1490
1491   const GLint kUniform1DesiredLocation = 10;
1492   const GLint kUniform2DesiredLocation = -1;
1493   const GLint kUniform3DesiredLocation = 5;
1494
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));
1514
1515   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
1516     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
1517     { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
1518     { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
1519   };
1520   ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
1521     { kUniform1Name,
1522       kUniform1Size,
1523       kUniform1Type,
1524       kUniform1FakeLocation,
1525       kUniform1RealLocation,
1526       kUniform1DesiredLocation,
1527       kUniform1Name,
1528     },
1529     { kUniform2Name,
1530       kUniform2Size,
1531       kUniform2Type,
1532       kUniform2FakeLocation,
1533       kUniform2RealLocation,
1534       kUniform2DesiredLocation,
1535       kUniform2Name,
1536     },
1537     { kUniform3BadName,
1538       kUniform3Size,
1539       kUniform3Type,
1540       kUniform3FakeLocation,
1541       kUniform3RealLocation,
1542       kUniform3DesiredLocation,
1543       kUniform3GoodName,
1544     },
1545   };
1546
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));
1553
1554   EXPECT_EQ(kUniform1DesiredLocation,
1555             program->GetUniformFakeLocation(kUniform1Name));
1556   EXPECT_EQ(kUniform3DesiredLocation,
1557             program->GetUniformFakeLocation(kUniform3BadName));
1558   EXPECT_EQ(kUniform3DesiredLocation,
1559             program->GetUniformFakeLocation(kUniform3GoodName));
1560 }
1561
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;
1570
1571   ProgramManagerWithCacheTest()
1572       : cache_(new MockProgramCache()),
1573         manager_(cache_.get(), kMaxVaryingVectors),
1574         vertex_shader_(NULL),
1575         fragment_shader_(NULL),
1576         program_(NULL) {
1577   }
1578   virtual ~ProgramManagerWithCacheTest() {
1579     manager_.Destroy(false);
1580     shader_manager_.Destroy(false);
1581   }
1582
1583  protected:
1584   virtual void SetUp() {
1585     GpuServiceTest::SetUp();
1586
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");
1595
1596     program_ = manager_.CreateProgram(
1597         kClientProgramId, kServiceProgramId);
1598     ASSERT_TRUE(program_ != NULL);
1599
1600     program_->AttachShader(&shader_manager_, vertex_shader_);
1601     program_->AttachShader(&shader_manager_, fragment_shader_);
1602   }
1603
1604   void SetShadersCompiled() {
1605     vertex_shader_->SetStatus(true, NULL, NULL);
1606     fragment_shader_->SetStatus(true, NULL, NULL);
1607   }
1608
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());
1616   }
1617
1618   void SetExpectationsForProgramCached() {
1619     SetExpectationsForProgramCached(program_,
1620                                     vertex_shader_,
1621                                     fragment_shader_);
1622   }
1623
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);
1636   }
1637
1638   void SetExpectationsForNotCachingProgram() {
1639     SetExpectationsForNotCachingProgram(program_,
1640                                         vertex_shader_,
1641                                         fragment_shader_);
1642   }
1643
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);
1656   }
1657
1658   void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
1659     SetExpectationsForProgramLoad(kServiceProgramId,
1660                                   program_,
1661                                   vertex_shader_,
1662                                   fragment_shader_,
1663                                   result);
1664   }
1665
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(),
1679                                   _))
1680         .WillOnce(Return(result));
1681   }
1682
1683   void SetExpectationsForProgramLoadSuccess() {
1684     SetExpectationsForProgramLoadSuccess(kServiceProgramId);
1685   }
1686
1687   void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
1688     TestHelper::SetupProgramSuccessExpectations(gl_.get(),
1689                                                 NULL,
1690                                                 0,
1691                                                 NULL,
1692                                                 0,
1693                                                 service_program_id);
1694   }
1695
1696   void SetExpectationsForProgramLink() {
1697     SetExpectationsForProgramLink(kServiceProgramId);
1698   }
1699
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);
1707     }
1708   }
1709
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));
1719   }
1720
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);
1729   }
1730
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);
1743   }
1744
1745   scoped_ptr<MockProgramCache> cache_;
1746   ProgramManager manager_;
1747
1748   Shader* vertex_shader_;
1749   Shader* fragment_shader_;
1750   Program* program_;
1751   ShaderManager shader_manager_;
1752 };
1753
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
1763
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)));
1770 }
1771
1772 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
1773   SetShadersCompiled();
1774   SetProgramCached();
1775
1776   SetExpectationsForNoCompile(vertex_shader_);
1777   SetExpectationsForNoCompile(fragment_shader_);
1778   SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
1779   SetExpectationsForNotCachingProgram();
1780   SetExpectationsForProgramLoadSuccess();
1781
1782   EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
1783       Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
1784 }
1785
1786 }  // namespace gles2
1787 }  // namespace gpu