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