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