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 void ShaderCacheCb(const std::string& key, const std::string& shader) {}
     40 }  // namespace
     41 
     42 class ProgramManagerTest : public testing::Test {
     43  public:
     44   ProgramManagerTest() : manager_(NULL) { }
     45   virtual ~ProgramManagerTest() {
     46     manager_.Destroy(false);
     47   }
     48 
     49  protected:
     50   virtual void SetUp() {
     51     gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
     52     ::gfx::GLInterface::SetGLInterface(gl_.get());
     53   }
     54 
     55   virtual void TearDown() {
     56     ::gfx::GLInterface::SetGLInterface(NULL);
     57     gl_.reset();
     58   }
     59 
     60   // Use StrictMock to make 100% sure we know how GL will be called.
     61   scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_;
     62   ProgramManager manager_;
     63 };
     64 
     65 TEST_F(ProgramManagerTest, Basic) {
     66   const GLuint kClient1Id = 1;
     67   const GLuint kService1Id = 11;
     68   const GLuint kClient2Id = 2;
     69   // Check we can create program.
     70   manager_.CreateProgram(kClient1Id, kService1Id);
     71   // Check program got created.
     72   Program* program1 = manager_.GetProgram(kClient1Id);
     73   ASSERT_TRUE(program1 != NULL);
     74   GLuint client_id = 0;
     75   EXPECT_TRUE(manager_.GetClientId(program1->service_id(), &client_id));
     76   EXPECT_EQ(kClient1Id, client_id);
     77   // Check we get nothing for a non-existent program.
     78   EXPECT_TRUE(manager_.GetProgram(kClient2Id) == NULL);
     79 }
     80 
     81 TEST_F(ProgramManagerTest, Destroy) {
     82   const GLuint kClient1Id = 1;
     83   const GLuint kService1Id = 11;
     84   // Check we can create program.
     85   Program* program0 = manager_.CreateProgram(kClient1Id, kService1Id);
     86   ASSERT_TRUE(program0 != NULL);
     87   // Check program got created.
     88   Program* program1 = manager_.GetProgram(kClient1Id);
     89   ASSERT_EQ(program0, program1);
     90   EXPECT_CALL(*gl_, DeleteProgram(kService1Id))
     91       .Times(1)
     92       .RetiresOnSaturation();
     93   manager_.Destroy(true);
     94   // Check the resources were released.
     95   program1 = manager_.GetProgram(kClient1Id);
     96   ASSERT_TRUE(program1 == NULL);
     97 }
     98 
     99 TEST_F(ProgramManagerTest, DeleteBug) {
    100   ShaderManager shader_manager;
    101   const GLuint kClient1Id = 1;
    102   const GLuint kClient2Id = 2;
    103   const GLuint kService1Id = 11;
    104   const GLuint kService2Id = 12;
    105   // Check we can create program.
    106   scoped_refptr<Program> program1(
    107       manager_.CreateProgram(kClient1Id, kService1Id));
    108   scoped_refptr<Program> program2(
    109       manager_.CreateProgram(kClient2Id, kService2Id));
    110   // Check program got created.
    111   ASSERT_TRUE(program1.get());
    112   ASSERT_TRUE(program2.get());
    113   manager_.UseProgram(program1.get());
    114   manager_.MarkAsDeleted(&shader_manager, program1.get());
    115   //  Program will be deleted when last ref is released.
    116   EXPECT_CALL(*gl_, DeleteProgram(kService2Id))
    117       .Times(1)
    118       .RetiresOnSaturation();
    119   manager_.MarkAsDeleted(&shader_manager, program2.get());
    120   EXPECT_TRUE(manager_.IsOwned(program1.get()));
    121   EXPECT_FALSE(manager_.IsOwned(program2.get()));
    122 }
    123 
    124 TEST_F(ProgramManagerTest, Program) {
    125   const GLuint kClient1Id = 1;
    126   const GLuint kService1Id = 11;
    127   // Check we can create program.
    128   Program* program1 = manager_.CreateProgram(
    129       kClient1Id, kService1Id);
    130   ASSERT_TRUE(program1);
    131   EXPECT_EQ(kService1Id, program1->service_id());
    132   EXPECT_FALSE(program1->InUse());
    133   EXPECT_FALSE(program1->IsValid());
    134   EXPECT_FALSE(program1->IsDeleted());
    135   EXPECT_FALSE(program1->CanLink());
    136   EXPECT_TRUE(program1->log_info() == NULL);
    137 }
    138 
    139 class ProgramManagerWithShaderTest : public testing::Test {
    140  public:
    141   ProgramManagerWithShaderTest()
    142       :  manager_(NULL), program_(NULL) {
    143   }
    144 
    145   virtual ~ProgramManagerWithShaderTest() {
    146     manager_.Destroy(false);
    147     shader_manager_.Destroy(false);
    148   }
    149 
    150   static const GLint kNumVertexAttribs = 16;
    151 
    152   static const GLuint kClientProgramId = 123;
    153   static const GLuint kServiceProgramId = 456;
    154   static const GLuint kVertexShaderClientId = 201;
    155   static const GLuint kFragmentShaderClientId = 202;
    156   static const GLuint kVertexShaderServiceId = 301;
    157   static const GLuint kFragmentShaderServiceId = 302;
    158 
    159   static const char* kAttrib1Name;
    160   static const char* kAttrib2Name;
    161   static const char* kAttrib3Name;
    162   static const GLint kAttrib1Size = 1;
    163   static const GLint kAttrib2Size = 1;
    164   static const GLint kAttrib3Size = 1;
    165   static const GLint kAttrib1Location = 0;
    166   static const GLint kAttrib2Location = 1;
    167   static const GLint kAttrib3Location = 2;
    168   static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
    169   static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
    170   static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
    171   static const GLint kInvalidAttribLocation = 30;
    172   static const GLint kBadAttribIndex = kNumVertexAttribs;
    173 
    174   static const char* kUniform1Name;
    175   static const char* kUniform2Name;
    176   static const char* kUniform3BadName;
    177   static const char* kUniform3GoodName;
    178   static const GLint kUniform1Size = 1;
    179   static const GLint kUniform2Size = 3;
    180   static const GLint kUniform3Size = 2;
    181   static const GLint kUniform1FakeLocation = 0;  // These are hard coded
    182   static const GLint kUniform2FakeLocation = 1;  // to match
    183   static const GLint kUniform3FakeLocation = 2;  // ProgramManager.
    184   static const GLint kUniform1RealLocation = 11;
    185   static const GLint kUniform2RealLocation = 22;
    186   static const GLint kUniform3RealLocation = 33;
    187   static const GLint kUniform1DesiredLocation = -1;
    188   static const GLint kUniform2DesiredLocation = -1;
    189   static const GLint kUniform3DesiredLocation = -1;
    190   static const GLenum kUniform1Type = GL_FLOAT_VEC4;
    191   static const GLenum kUniform2Type = GL_INT_VEC2;
    192   static const GLenum kUniform3Type = GL_FLOAT_VEC3;
    193   static const GLint kInvalidUniformLocation = 30;
    194   static const GLint kBadUniformIndex = 1000;
    195 
    196   static const size_t kNumAttribs;
    197   static const size_t kNumUniforms;
    198 
    199  protected:
    200   typedef TestHelper::AttribInfo AttribInfo;
    201   typedef TestHelper::UniformInfo UniformInfo;
    202 
    203   virtual void SetUp() {
    204     gl_.reset(new StrictMock<gfx::MockGLInterface>());
    205     ::gfx::GLInterface::SetGLInterface(gl_.get());
    206 
    207     SetupDefaultShaderExpectations();
    208 
    209     Shader* vertex_shader = shader_manager_.CreateShader(
    210         kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
    211     Shader* fragment_shader =
    212         shader_manager_.CreateShader(
    213             kFragmentShaderClientId, kFragmentShaderServiceId,
    214             GL_FRAGMENT_SHADER);
    215     ASSERT_TRUE(vertex_shader != NULL);
    216     ASSERT_TRUE(fragment_shader != NULL);
    217     vertex_shader->SetStatus(true, NULL, NULL);
    218     fragment_shader->SetStatus(true, NULL, NULL);
    219 
    220     program_ = manager_.CreateProgram(
    221         kClientProgramId, kServiceProgramId);
    222     ASSERT_TRUE(program_ != NULL);
    223 
    224     program_->AttachShader(&shader_manager_, vertex_shader);
    225     program_->AttachShader(&shader_manager_, fragment_shader);
    226     program_->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
    227   }
    228 
    229   void SetupShader(AttribInfo* attribs, size_t num_attribs,
    230                    UniformInfo* uniforms, size_t num_uniforms,
    231                    GLuint service_id) {
    232     TestHelper::SetupShader(
    233         gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
    234   }
    235 
    236   void SetupDefaultShaderExpectations() {
    237     SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
    238                 kServiceProgramId);
    239   }
    240 
    241   void SetupExpectationsForClearingUniforms(
    242       UniformInfo* uniforms, size_t num_uniforms) {
    243     TestHelper::SetupExpectationsForClearingUniforms(
    244         gl_.get(), uniforms, num_uniforms);
    245   }
    246 
    247   virtual void TearDown() {
    248     ::gfx::GLInterface::SetGLInterface(NULL);
    249   }
    250 
    251   // Return true if link status matches expected_link_status
    252   bool LinkAsExpected(Program* program,
    253                       bool expected_link_status) {
    254     GLuint service_id = program->service_id();
    255     if (expected_link_status) {
    256       SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
    257                   service_id);
    258     }
    259     program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
    260     GLint link_status;
    261     program->GetProgramiv(GL_LINK_STATUS, &link_status);
    262     return (static_cast<bool>(link_status) == expected_link_status);
    263   }
    264 
    265   static AttribInfo kAttribs[];
    266   static UniformInfo kUniforms[];
    267 
    268   scoped_ptr<StrictMock<gfx::MockGLInterface> > gl_;
    269 
    270   ProgramManager manager_;
    271   Program* program_;
    272   ShaderManager shader_manager_;
    273 };
    274 
    275 ProgramManagerWithShaderTest::AttribInfo
    276     ProgramManagerWithShaderTest::kAttribs[] = {
    277   { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
    278   { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
    279   { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
    280 };
    281 
    282 // GCC requires these declarations, but MSVC requires they not be present
    283 #ifndef COMPILER_MSVC
    284 const GLint ProgramManagerWithShaderTest::kNumVertexAttribs;
    285 const GLuint ProgramManagerWithShaderTest::kClientProgramId;
    286 const GLuint ProgramManagerWithShaderTest::kServiceProgramId;
    287 const GLuint ProgramManagerWithShaderTest::kVertexShaderClientId;
    288 const GLuint ProgramManagerWithShaderTest::kFragmentShaderClientId;
    289 const GLuint ProgramManagerWithShaderTest::kVertexShaderServiceId;
    290 const GLuint ProgramManagerWithShaderTest::kFragmentShaderServiceId;
    291 const GLint ProgramManagerWithShaderTest::kAttrib1Size;
    292 const GLint ProgramManagerWithShaderTest::kAttrib2Size;
    293 const GLint ProgramManagerWithShaderTest::kAttrib3Size;
    294 const GLint ProgramManagerWithShaderTest::kAttrib1Location;
    295 const GLint ProgramManagerWithShaderTest::kAttrib2Location;
    296 const GLint ProgramManagerWithShaderTest::kAttrib3Location;
    297 const GLenum ProgramManagerWithShaderTest::kAttrib1Type;
    298 const GLenum ProgramManagerWithShaderTest::kAttrib2Type;
    299 const GLenum ProgramManagerWithShaderTest::kAttrib3Type;
    300 const GLint ProgramManagerWithShaderTest::kInvalidAttribLocation;
    301 const GLint ProgramManagerWithShaderTest::kBadAttribIndex;
    302 const GLint ProgramManagerWithShaderTest::kUniform1Size;
    303 const GLint ProgramManagerWithShaderTest::kUniform2Size;
    304 const GLint ProgramManagerWithShaderTest::kUniform3Size;
    305 const GLint ProgramManagerWithShaderTest::kUniform1FakeLocation;
    306 const GLint ProgramManagerWithShaderTest::kUniform2FakeLocation;
    307 const GLint ProgramManagerWithShaderTest::kUniform3FakeLocation;
    308 const GLint ProgramManagerWithShaderTest::kUniform1RealLocation;
    309 const GLint ProgramManagerWithShaderTest::kUniform2RealLocation;
    310 const GLint ProgramManagerWithShaderTest::kUniform3RealLocation;
    311 const GLint ProgramManagerWithShaderTest::kUniform1DesiredLocation;
    312 const GLint ProgramManagerWithShaderTest::kUniform2DesiredLocation;
    313 const GLint ProgramManagerWithShaderTest::kUniform3DesiredLocation;
    314 const GLenum ProgramManagerWithShaderTest::kUniform1Type;
    315 const GLenum ProgramManagerWithShaderTest::kUniform2Type;
    316 const GLenum ProgramManagerWithShaderTest::kUniform3Type;
    317 const GLint ProgramManagerWithShaderTest::kInvalidUniformLocation;
    318 const GLint ProgramManagerWithShaderTest::kBadUniformIndex;
    319 #endif
    320 
    321 const size_t ProgramManagerWithShaderTest::kNumAttribs =
    322     arraysize(ProgramManagerWithShaderTest::kAttribs);
    323 
    324 ProgramManagerWithShaderTest::UniformInfo
    325     ProgramManagerWithShaderTest::kUniforms[] = {
    326   { kUniform1Name,
    327     kUniform1Size,
    328     kUniform1Type,
    329     kUniform1FakeLocation,
    330     kUniform1RealLocation,
    331     kUniform1DesiredLocation,
    332     kUniform1Name,
    333   },
    334   { kUniform2Name,
    335     kUniform2Size,
    336     kUniform2Type,
    337     kUniform2FakeLocation,
    338     kUniform2RealLocation,
    339     kUniform2DesiredLocation,
    340     kUniform2Name,
    341   },
    342   { kUniform3BadName,
    343     kUniform3Size,
    344     kUniform3Type,
    345     kUniform3FakeLocation,
    346     kUniform3RealLocation,
    347     kUniform3DesiredLocation,
    348     kUniform3GoodName,
    349   },
    350 };
    351 
    352 const size_t ProgramManagerWithShaderTest::kNumUniforms =
    353     arraysize(ProgramManagerWithShaderTest::kUniforms);
    354 
    355 const char* ProgramManagerWithShaderTest::kAttrib1Name = "attrib1";
    356 const char* ProgramManagerWithShaderTest::kAttrib2Name = "attrib2";
    357 const char* ProgramManagerWithShaderTest::kAttrib3Name = "attrib3";
    358 const char* ProgramManagerWithShaderTest::kUniform1Name = "uniform1";
    359 // Correctly has array spec.
    360 const char* ProgramManagerWithShaderTest::kUniform2Name = "uniform2[0]";
    361 // Incorrectly missing array spec.
    362 const char* ProgramManagerWithShaderTest::kUniform3BadName = "uniform3";
    363 const char* ProgramManagerWithShaderTest::kUniform3GoodName = "uniform3[0]";
    364 
    365 TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) {
    366   const Program* program = manager_.GetProgram(kClientProgramId);
    367   ASSERT_TRUE(program != NULL);
    368   const Program::AttribInfoVector& infos =
    369       program->GetAttribInfos();
    370   ASSERT_EQ(kNumAttribs, infos.size());
    371   for (size_t ii = 0; ii < kNumAttribs; ++ii) {
    372     const Program::VertexAttrib& info = infos[ii];
    373     const AttribInfo& expected = kAttribs[ii];
    374     EXPECT_EQ(expected.size, info.size);
    375     EXPECT_EQ(expected.type, info.type);
    376     EXPECT_EQ(expected.location, info.location);
    377     EXPECT_STREQ(expected.name, info.name.c_str());
    378   }
    379 }
    380 
    381 TEST_F(ProgramManagerWithShaderTest, GetAttribInfo) {
    382   const GLint kValidIndex = 1;
    383   const GLint kInvalidIndex = 1000;
    384   const Program* program = manager_.GetProgram(kClientProgramId);
    385   ASSERT_TRUE(program != NULL);
    386   const Program::VertexAttrib* info =
    387       program->GetAttribInfo(kValidIndex);
    388   ASSERT_TRUE(info != NULL);
    389   EXPECT_EQ(kAttrib2Size, info->size);
    390   EXPECT_EQ(kAttrib2Type, info->type);
    391   EXPECT_EQ(kAttrib2Location, info->location);
    392   EXPECT_STREQ(kAttrib2Name, info->name.c_str());
    393   EXPECT_TRUE(program->GetAttribInfo(kInvalidIndex) == NULL);
    394 }
    395 
    396 TEST_F(ProgramManagerWithShaderTest, GetAttribLocation) {
    397   const char* kInvalidName = "foo";
    398   const Program* program = manager_.GetProgram(kClientProgramId);
    399   ASSERT_TRUE(program != NULL);
    400   EXPECT_EQ(kAttrib2Location, program->GetAttribLocation(kAttrib2Name));
    401   EXPECT_EQ(-1, program->GetAttribLocation(kInvalidName));
    402 }
    403 
    404 TEST_F(ProgramManagerWithShaderTest, GetUniformInfo) {
    405   const GLint kInvalidIndex = 1000;
    406   const Program* program = manager_.GetProgram(kClientProgramId);
    407   ASSERT_TRUE(program != NULL);
    408   const Program::UniformInfo* info =
    409       program->GetUniformInfo(0);
    410   ASSERT_TRUE(info != NULL);
    411   EXPECT_EQ(kUniform1Size, info->size);
    412   EXPECT_EQ(kUniform1Type, info->type);
    413   EXPECT_EQ(kUniform1RealLocation, info->element_locations[0]);
    414   EXPECT_STREQ(kUniform1Name, info->name.c_str());
    415   info = program->GetUniformInfo(1);
    416   ASSERT_TRUE(info != NULL);
    417   EXPECT_EQ(kUniform2Size, info->size);
    418   EXPECT_EQ(kUniform2Type, info->type);
    419   EXPECT_EQ(kUniform2RealLocation, info->element_locations[0]);
    420   EXPECT_STREQ(kUniform2Name, info->name.c_str());
    421   info = program->GetUniformInfo(2);
    422   // We emulate certain OpenGL drivers by supplying the name without
    423   // the array spec. Our implementation should correctly add the required spec.
    424   ASSERT_TRUE(info != NULL);
    425   EXPECT_EQ(kUniform3Size, info->size);
    426   EXPECT_EQ(kUniform3Type, info->type);
    427   EXPECT_EQ(kUniform3RealLocation, info->element_locations[0]);
    428   EXPECT_STREQ(kUniform3GoodName, info->name.c_str());
    429   EXPECT_TRUE(program->GetUniformInfo(kInvalidIndex) == NULL);
    430 }
    431 
    432 TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) {
    433   static const GLuint kClientProgramId = 124;
    434   static const GLuint kServiceProgramId = 457;
    435   Program* program = manager_.CreateProgram(
    436       kClientProgramId, kServiceProgramId);
    437   ASSERT_TRUE(program != NULL);
    438   EXPECT_FALSE(program->CanLink());
    439   const GLuint kVShaderClientId = 2001;
    440   const GLuint kFShaderClientId = 2002;
    441   const GLuint kVShaderServiceId = 3001;
    442   const GLuint kFShaderServiceId = 3002;
    443   Shader* vshader = shader_manager_.CreateShader(
    444       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    445   ASSERT_TRUE(vshader != NULL);
    446   vshader->SetStatus(true, "", NULL);
    447   Shader* fshader = shader_manager_.CreateShader(
    448       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    449   ASSERT_TRUE(fshader != NULL);
    450   fshader->SetStatus(true, "", NULL);
    451   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    452   EXPECT_FALSE(program->CanLink());
    453   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    454   EXPECT_TRUE(program->CanLink());
    455   program->DetachShader(&shader_manager_, vshader);
    456   EXPECT_FALSE(program->CanLink());
    457   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    458   EXPECT_TRUE(program->CanLink());
    459   program->DetachShader(&shader_manager_, fshader);
    460   EXPECT_FALSE(program->CanLink());
    461   EXPECT_FALSE(program->AttachShader(&shader_manager_, vshader));
    462   EXPECT_FALSE(program->CanLink());
    463   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    464   EXPECT_TRUE(program->CanLink());
    465   vshader->SetStatus(false, "", NULL);
    466   EXPECT_FALSE(program->CanLink());
    467   vshader->SetStatus(true, "", NULL);
    468   EXPECT_TRUE(program->CanLink());
    469   fshader->SetStatus(false, "", NULL);
    470   EXPECT_FALSE(program->CanLink());
    471   fshader->SetStatus(true, "", NULL);
    472   EXPECT_TRUE(program->CanLink());
    473   EXPECT_TRUE(program->DetachShader(&shader_manager_, fshader));
    474   EXPECT_FALSE(program->DetachShader(&shader_manager_, fshader));
    475 }
    476 
    477 TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) {
    478   const Program* program = manager_.GetProgram(kClientProgramId);
    479   ASSERT_TRUE(program != NULL);
    480   EXPECT_EQ(kUniform1FakeLocation,
    481             program->GetUniformFakeLocation(kUniform1Name));
    482   EXPECT_EQ(kUniform2FakeLocation,
    483             program->GetUniformFakeLocation(kUniform2Name));
    484   EXPECT_EQ(kUniform3FakeLocation,
    485              program->GetUniformFakeLocation(kUniform3BadName));
    486   // Check we can get uniform2 as "uniform2" even though the name is
    487   // "uniform2[0]"
    488   EXPECT_EQ(kUniform2FakeLocation,
    489             program->GetUniformFakeLocation("uniform2"));
    490   // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
    491   // returning "uniform3"
    492   EXPECT_EQ(kUniform3FakeLocation,
    493             program->GetUniformFakeLocation(kUniform3GoodName));
    494   // Check that we can get the locations of the array elements > 1
    495   EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 1),
    496             program->GetUniformFakeLocation("uniform2[1]"));
    497   EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2),
    498             program->GetUniformFakeLocation("uniform2[2]"));
    499   EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]"));
    500   EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform3FakeLocation, 1),
    501             program->GetUniformFakeLocation("uniform3[1]"));
    502   EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]"));
    503 }
    504 
    505 TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) {
    506   const GLint kInvalidLocation = 1234;
    507   const Program::UniformInfo* info;
    508   const Program* program = manager_.GetProgram(kClientProgramId);
    509   GLint real_location = -1;
    510   GLint array_index = -1;
    511   ASSERT_TRUE(program != NULL);
    512   info = program->GetUniformInfoByFakeLocation(
    513       kUniform2FakeLocation, &real_location, &array_index);
    514   EXPECT_EQ(kUniform2RealLocation, real_location);
    515   EXPECT_EQ(0, array_index);
    516   ASSERT_TRUE(info != NULL);
    517   EXPECT_EQ(kUniform2Type, info->type);
    518   real_location = -1;
    519   array_index = -1;
    520   info = program->GetUniformInfoByFakeLocation(
    521       kInvalidLocation, &real_location, &array_index);
    522   EXPECT_TRUE(info == NULL);
    523   EXPECT_EQ(-1, real_location);
    524   EXPECT_EQ(-1, array_index);
    525   GLint loc = program->GetUniformFakeLocation("uniform2[2]");
    526   info = program->GetUniformInfoByFakeLocation(
    527       loc, &real_location, &array_index);
    528   ASSERT_TRUE(info != NULL);
    529   EXPECT_EQ(kUniform2RealLocation + 2 * 2, real_location);
    530   EXPECT_EQ(2, array_index);
    531 }
    532 
    533 // Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
    534 // that start with "gl_". Our implementation catches these and does not allow
    535 // them back to client.
    536 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
    537   static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
    538   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
    539     { kUniform1Name,
    540       kUniform1Size,
    541       kUniform1Type,
    542       kUniform1FakeLocation,
    543       kUniform1RealLocation,
    544       kUniform1DesiredLocation,
    545       kUniform1Name,
    546     },
    547     { kUniform2Name,
    548       kUniform2Size,
    549       kUniform2Type,
    550       kUniform2FakeLocation,
    551       kUniform2RealLocation,
    552       kUniform2DesiredLocation,
    553       kUniform2Name,
    554     },
    555     { kUniform3BadName,
    556       kUniform3Size,
    557       kUniform3Type,
    558       kUniform3FakeLocation,
    559       kUniform3RealLocation,
    560       kUniform3DesiredLocation,
    561       kUniform3GoodName,
    562     },
    563   };
    564   const size_t kNumUniforms = arraysize(kUniforms);
    565   static const GLuint kClientProgramId = 1234;
    566   static const GLuint kServiceProgramId = 5679;
    567   const GLuint kVShaderClientId = 2001;
    568   const GLuint kFShaderClientId = 2002;
    569   const GLuint kVShaderServiceId = 3001;
    570   const GLuint kFShaderServiceId = 3002;
    571   SetupShader(
    572       kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
    573   Shader* vshader = shader_manager_.CreateShader(
    574       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    575   ASSERT_TRUE(vshader != NULL);
    576   vshader->SetStatus(true, "", NULL);
    577   Shader* fshader = shader_manager_.CreateShader(
    578       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    579   ASSERT_TRUE(fshader != NULL);
    580   fshader->SetStatus(true, "", NULL);
    581   Program* program =
    582       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
    583   ASSERT_TRUE(program != NULL);
    584   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    585   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    586   program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
    587   GLint value = 0;
    588   program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
    589   EXPECT_EQ(3, value);
    590   // Check that we skipped the "gl_" uniform.
    591   program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
    592   EXPECT_EQ(2, value);
    593   // Check that our max length adds room for the array spec and is not as long
    594   // as the "gl_" uniform we skipped.
    595   // +4u is to account for "gl_" and NULL terminator.
    596   program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
    597   EXPECT_EQ(strlen(kUniform3BadName) + 4u, static_cast<size_t>(value));
    598 }
    599 
    600 // Test the bug comparing similar array names is fixed.
    601 TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
    602   static const char* kUniform2Name = "u_nameLong[0]";
    603   static const char* kUniform3Name = "u_name[0]";
    604   static const GLint kUniform2Size = 2;
    605   static const GLint kUniform3Size = 2;
    606   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
    607     { kUniform1Name,
    608       kUniform1Size,
    609       kUniform1Type,
    610       kUniform1FakeLocation,
    611       kUniform1RealLocation,
    612       kUniform1DesiredLocation,
    613       kUniform1Name,
    614     },
    615     { kUniform2Name,
    616       kUniform2Size,
    617       kUniform2Type,
    618       kUniform2FakeLocation,
    619       kUniform2RealLocation,
    620       kUniform2DesiredLocation,
    621       kUniform2Name,
    622     },
    623     { kUniform3Name,
    624       kUniform3Size,
    625       kUniform3Type,
    626       kUniform3FakeLocation,
    627       kUniform3RealLocation,
    628       kUniform3DesiredLocation,
    629       kUniform3Name,
    630     },
    631   };
    632   const size_t kNumUniforms = arraysize(kUniforms);
    633   static const GLuint kClientProgramId = 1234;
    634   static const GLuint kServiceProgramId = 5679;
    635   const GLuint kVShaderClientId = 2001;
    636   const GLuint kFShaderClientId = 2002;
    637   const GLuint kVShaderServiceId = 3001;
    638   const GLuint kFShaderServiceId = 3002;
    639   SetupShader(
    640       kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
    641   Shader* vshader = shader_manager_.CreateShader(
    642       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    643   ASSERT_TRUE(vshader != NULL);
    644   vshader->SetStatus(true, "", NULL);
    645   Shader* fshader = shader_manager_.CreateShader(
    646       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    647   ASSERT_TRUE(fshader != NULL);
    648   fshader->SetStatus(true, "", NULL);
    649   Program* program =
    650       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
    651   ASSERT_TRUE(program != NULL);
    652   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    653   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    654   program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
    655 
    656   // Check that we get the correct locations.
    657   EXPECT_EQ(kUniform2FakeLocation,
    658             program->GetUniformFakeLocation(kUniform2Name));
    659   EXPECT_EQ(kUniform3FakeLocation,
    660             program->GetUniformFakeLocation(kUniform3Name));
    661 }
    662 
    663 // Some GL drivers incorrectly return the wrong type. For example they return
    664 // GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
    665 TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
    666   static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
    667   static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
    668   static GLenum kUniform2BadType = GL_FLOAT_VEC3;
    669   static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
    670   MockShaderTranslator shader_translator;
    671   ShaderTranslator::VariableMap attrib_map;
    672   ShaderTranslator::VariableMap uniform_map;
    673   attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
    674       kAttrib1Type, kAttrib1Size, kAttrib1Name);
    675   attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
    676       kAttrib2GoodType, kAttrib2Size, kAttrib2Name);
    677   attrib_map[kAttrib3Name] = ShaderTranslatorInterface::VariableInfo(
    678       kAttrib3Type, kAttrib3Size, kAttrib3Name);
    679   uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
    680       kUniform1Type, kUniform1Size, kUniform1Name);
    681   uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
    682       kUniform2GoodType, kUniform2Size, kUniform2Name);
    683   uniform_map[kUniform3GoodName] = ShaderTranslatorInterface::VariableInfo(
    684       kUniform3Type, kUniform3Size, kUniform3GoodName);
    685   EXPECT_CALL(shader_translator, attrib_map())
    686       .WillRepeatedly(ReturnRef(attrib_map));
    687   EXPECT_CALL(shader_translator, uniform_map())
    688       .WillRepeatedly(ReturnRef(uniform_map));
    689   ShaderTranslator::NameMap name_map;
    690   EXPECT_CALL(shader_translator, name_map())
    691       .WillRepeatedly(ReturnRef(name_map));
    692   const GLuint kVShaderClientId = 2001;
    693   const GLuint kFShaderClientId = 2002;
    694   const GLuint kVShaderServiceId = 3001;
    695   const GLuint kFShaderServiceId = 3002;
    696   Shader* vshader = shader_manager_.CreateShader(
    697       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    698   ASSERT_TRUE(vshader != NULL);
    699   vshader->SetStatus(true, "", &shader_translator);
    700   Shader* fshader = shader_manager_.CreateShader(
    701       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    702   ASSERT_TRUE(fshader != NULL);
    703   fshader->SetStatus(true, "", &shader_translator);
    704   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
    705     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
    706     { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
    707     { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
    708   };
    709   static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
    710     { kUniform1Name,
    711       kUniform1Size,
    712       kUniform1Type,
    713       kUniform1FakeLocation,
    714       kUniform1RealLocation,
    715       kUniform1DesiredLocation,
    716       kUniform1Name,
    717     },
    718     { kUniform2Name,
    719       kUniform2Size,
    720       kUniform2BadType,
    721       kUniform2FakeLocation,
    722       kUniform2RealLocation,
    723       kUniform2DesiredLocation,
    724       kUniform2Name,
    725     },
    726     { kUniform3BadName,
    727       kUniform3Size,
    728       kUniform3Type,
    729       kUniform3FakeLocation,
    730       kUniform3RealLocation,
    731       kUniform3DesiredLocation,
    732       kUniform3GoodName,
    733     },
    734   };
    735   const size_t kNumAttribs= arraysize(kAttribs);
    736   const size_t kNumUniforms = arraysize(kUniforms);
    737   static const GLuint kClientProgramId = 1234;
    738   static const GLuint kServiceProgramId = 5679;
    739   SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
    740               kServiceProgramId);
    741   Program* program = manager_.CreateProgram(
    742       kClientProgramId, kServiceProgramId);
    743   ASSERT_TRUE(program!= NULL);
    744   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    745   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    746   program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
    747   // Check that we got the good type, not the bad.
    748   // Check Attribs
    749   for (unsigned index = 0; index < kNumAttribs; ++index) {
    750     const Program::VertexAttrib* attrib_info =
    751         program->GetAttribInfo(index);
    752     ASSERT_TRUE(attrib_info != NULL);
    753     ShaderTranslator::VariableMap::const_iterator it = attrib_map.find(
    754         attrib_info->name);
    755     ASSERT_TRUE(it != attrib_map.end());
    756     EXPECT_EQ(it->first, attrib_info->name);
    757     EXPECT_EQ(static_cast<GLenum>(it->second.type), attrib_info->type);
    758     EXPECT_EQ(it->second.size, attrib_info->size);
    759     EXPECT_EQ(it->second.name, attrib_info->name);
    760   }
    761   // Check Uniforms
    762   for (unsigned index = 0; index < kNumUniforms; ++index) {
    763     const Program::UniformInfo* uniform_info =
    764         program->GetUniformInfo(index);
    765     ASSERT_TRUE(uniform_info != NULL);
    766     ShaderTranslator::VariableMap::const_iterator it = uniform_map.find(
    767         uniform_info->name);
    768     ASSERT_TRUE(it != uniform_map.end());
    769     EXPECT_EQ(it->first, uniform_info->name);
    770     EXPECT_EQ(static_cast<GLenum>(it->second.type), uniform_info->type);
    771     EXPECT_EQ(it->second.size, uniform_info->size);
    772     EXPECT_EQ(it->second.name, uniform_info->name);
    773   }
    774 }
    775 
    776 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
    777   static const GLuint kClientProgramId = 124;
    778   static const GLuint kServiceProgramId = 457;
    779   Program* program = manager_.CreateProgram(
    780       kClientProgramId, kServiceProgramId);
    781   ASSERT_TRUE(program != NULL);
    782   EXPECT_FALSE(program->CanLink());
    783   const GLuint kVShaderClientId = 2001;
    784   const GLuint kFShaderClientId = 2002;
    785   const GLuint kVShaderServiceId = 3001;
    786   const GLuint kFShaderServiceId = 3002;
    787   Shader* vshader = shader_manager_.CreateShader(
    788       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    789   ASSERT_TRUE(vshader != NULL);
    790   vshader->SetStatus(true, "", NULL);
    791   Shader* fshader = shader_manager_.CreateShader(
    792       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    793   ASSERT_TRUE(fshader != NULL);
    794   fshader->SetStatus(true, "", NULL);
    795   EXPECT_FALSE(vshader->InUse());
    796   EXPECT_FALSE(fshader->InUse());
    797   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    798   EXPECT_TRUE(vshader->InUse());
    799   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    800   EXPECT_TRUE(fshader->InUse());
    801   EXPECT_TRUE(program->CanLink());
    802   EXPECT_FALSE(program->InUse());
    803   EXPECT_FALSE(program->IsDeleted());
    804   manager_.UseProgram(program);
    805   EXPECT_TRUE(program->InUse());
    806   manager_.UseProgram(program);
    807   EXPECT_TRUE(program->InUse());
    808   manager_.MarkAsDeleted(&shader_manager_, program);
    809   EXPECT_TRUE(program->IsDeleted());
    810   Program* info2 = manager_.GetProgram(kClientProgramId);
    811   EXPECT_EQ(program, info2);
    812   manager_.UnuseProgram(&shader_manager_, program);
    813   EXPECT_TRUE(program->InUse());
    814   // this should delete the info.
    815   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
    816       .Times(1)
    817       .RetiresOnSaturation();
    818   manager_.UnuseProgram(&shader_manager_, program);
    819   info2 = manager_.GetProgram(kClientProgramId);
    820   EXPECT_TRUE(info2 == NULL);
    821   EXPECT_FALSE(vshader->InUse());
    822   EXPECT_FALSE(fshader->InUse());
    823 }
    824 
    825 TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
    826   static const GLuint kClientProgramId = 124;
    827   static const GLuint kServiceProgramId = 457;
    828   Program* program = manager_.CreateProgram(
    829       kClientProgramId, kServiceProgramId);
    830   ASSERT_TRUE(program != NULL);
    831   EXPECT_FALSE(program->CanLink());
    832   const GLuint kVShaderClientId = 2001;
    833   const GLuint kFShaderClientId = 2002;
    834   const GLuint kVShaderServiceId = 3001;
    835   const GLuint kFShaderServiceId = 3002;
    836   Shader* vshader = shader_manager_.CreateShader(
    837       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    838   ASSERT_TRUE(vshader != NULL);
    839   vshader->SetStatus(true, "", NULL);
    840   Shader* fshader = shader_manager_.CreateShader(
    841       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    842   ASSERT_TRUE(fshader != NULL);
    843   fshader->SetStatus(true, "", NULL);
    844   EXPECT_FALSE(vshader->InUse());
    845   EXPECT_FALSE(fshader->InUse());
    846   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    847   EXPECT_TRUE(vshader->InUse());
    848   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    849   EXPECT_TRUE(fshader->InUse());
    850   EXPECT_TRUE(program->CanLink());
    851   EXPECT_FALSE(program->InUse());
    852   EXPECT_FALSE(program->IsDeleted());
    853   manager_.UseProgram(program);
    854   EXPECT_TRUE(program->InUse());
    855   manager_.UseProgram(program);
    856   EXPECT_TRUE(program->InUse());
    857   manager_.UnuseProgram(&shader_manager_, program);
    858   EXPECT_TRUE(program->InUse());
    859   manager_.UnuseProgram(&shader_manager_, program);
    860   EXPECT_FALSE(program->InUse());
    861   Program* info2 = manager_.GetProgram(kClientProgramId);
    862   EXPECT_EQ(program, info2);
    863   // this should delete the program.
    864   EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
    865       .Times(1)
    866       .RetiresOnSaturation();
    867   manager_.MarkAsDeleted(&shader_manager_, program);
    868   info2 = manager_.GetProgram(kClientProgramId);
    869   EXPECT_TRUE(info2 == NULL);
    870   EXPECT_FALSE(vshader->InUse());
    871   EXPECT_FALSE(fshader->InUse());
    872 }
    873 
    874 TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
    875   CommonDecoder::Bucket bucket;
    876   const Program* program = manager_.GetProgram(kClientProgramId);
    877   ASSERT_TRUE(program != NULL);
    878   program->GetProgramInfo(&manager_, &bucket);
    879   ProgramInfoHeader* header =
    880       bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
    881   ASSERT_TRUE(header != NULL);
    882   EXPECT_EQ(1u, header->link_status);
    883   EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
    884   EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
    885   const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
    886       sizeof(*header),
    887       sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
    888   ASSERT_TRUE(inputs != NULL);
    889   const ProgramInput* input = inputs;
    890   // TODO(gman): Don't assume these are in order.
    891   for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
    892     const AttribInfo& expected = kAttribs[ii];
    893     EXPECT_EQ(expected.size, input->size);
    894     EXPECT_EQ(expected.type, input->type);
    895     const int32* location = bucket.GetDataAs<const int32*>(
    896         input->location_offset, sizeof(int32));
    897     ASSERT_TRUE(location != NULL);
    898     EXPECT_EQ(expected.location, *location);
    899     const char* name_buf = bucket.GetDataAs<const char*>(
    900         input->name_offset, input->name_length);
    901     ASSERT_TRUE(name_buf != NULL);
    902     std::string name(name_buf, input->name_length);
    903     EXPECT_STREQ(expected.name, name.c_str());
    904     ++input;
    905   }
    906   // TODO(gman): Don't assume these are in order.
    907   for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
    908     const UniformInfo& expected = kUniforms[ii];
    909     EXPECT_EQ(expected.size, input->size);
    910     EXPECT_EQ(expected.type, input->type);
    911     const int32* locations = bucket.GetDataAs<const int32*>(
    912         input->location_offset, sizeof(int32) * input->size);
    913     ASSERT_TRUE(locations != NULL);
    914     for (int32 jj = 0; jj < input->size; ++jj) {
    915       EXPECT_EQ(
    916           ProgramManager::MakeFakeLocation(expected.fake_location, jj),
    917           locations[jj]);
    918     }
    919     const char* name_buf = bucket.GetDataAs<const char*>(
    920         input->name_offset, input->name_length);
    921     ASSERT_TRUE(name_buf != NULL);
    922     std::string name(name_buf, input->name_length);
    923     EXPECT_STREQ(expected.good_name, name.c_str());
    924     ++input;
    925   }
    926   EXPECT_EQ(header->num_attribs + header->num_uniforms,
    927             static_cast<uint32>(input - inputs));
    928 }
    929 
    930 TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
    931   // Set up shader
    932   const GLuint kVShaderClientId = 1;
    933   const GLuint kVShaderServiceId = 11;
    934   const GLuint kFShaderClientId = 2;
    935   const GLuint kFShaderServiceId = 12;
    936   MockShaderTranslator shader_translator;
    937   ShaderTranslator::VariableMap attrib_map;
    938   for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
    939     attrib_map[kAttribs[ii].name] = ShaderTranslatorInterface::VariableInfo(
    940         kAttribs[ii].type, kAttribs[ii].size, kAttribs[ii].name);
    941   }
    942   ShaderTranslator::VariableMap uniform_map;
    943   EXPECT_CALL(shader_translator, attrib_map())
    944       .WillRepeatedly(ReturnRef(attrib_map));
    945   EXPECT_CALL(shader_translator, uniform_map())
    946       .WillRepeatedly(ReturnRef(uniform_map));
    947   ShaderTranslator::NameMap name_map;
    948   EXPECT_CALL(shader_translator, name_map())
    949       .WillRepeatedly(ReturnRef(name_map));
    950   // Check we can create shader.
    951   Shader* vshader = shader_manager_.CreateShader(
    952       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
    953   Shader* fshader = shader_manager_.CreateShader(
    954       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
    955   // Check shader got created.
    956   ASSERT_TRUE(vshader != NULL && fshader != NULL);
    957   // Set Status
    958   vshader->SetStatus(true, "", &shader_translator);
    959   // Check attrib infos got copied.
    960   for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
    961        it != attrib_map.end(); ++it) {
    962     const Shader::VariableInfo* variable_info =
    963         vshader->GetAttribInfo(it->first);
    964     ASSERT_TRUE(variable_info != NULL);
    965     EXPECT_EQ(it->second.type, variable_info->type);
    966     EXPECT_EQ(it->second.size, variable_info->size);
    967     EXPECT_EQ(it->second.name, variable_info->name);
    968   }
    969   fshader->SetStatus(true, "", NULL);
    970 
    971   // Set up program
    972   const GLuint kClientProgramId = 6666;
    973   const GLuint kServiceProgramId = 8888;
    974   Program* program =
    975       manager_.CreateProgram(kClientProgramId, kServiceProgramId);
    976   ASSERT_TRUE(program != NULL);
    977   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
    978   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
    979 
    980   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
    981   EXPECT_TRUE(LinkAsExpected(program, true));
    982 
    983   program->SetAttribLocationBinding(kAttrib1Name, 0);
    984   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
    985   EXPECT_TRUE(LinkAsExpected(program, true));
    986 
    987   program->SetAttribLocationBinding("xxx", 0);
    988   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
    989   EXPECT_TRUE(LinkAsExpected(program, true));
    990 
    991   program->SetAttribLocationBinding(kAttrib2Name, 1);
    992   EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
    993   EXPECT_TRUE(LinkAsExpected(program, true));
    994 
    995   program->SetAttribLocationBinding(kAttrib2Name, 0);
    996   EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
    997   EXPECT_TRUE(LinkAsExpected(program, false));
    998 }
    999 
   1000 TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
   1001   const GLuint kVShaderClientId = 2001;
   1002   const GLuint kFShaderClientId = 2002;
   1003   const GLuint kVShaderServiceId = 3001;
   1004   const GLuint kFShaderServiceId = 3002;
   1005   Shader* vshader = shader_manager_.CreateShader(
   1006       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
   1007   ASSERT_TRUE(vshader != NULL);
   1008   vshader->SetStatus(true, NULL, NULL);
   1009   Shader* fshader = shader_manager_.CreateShader(
   1010       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
   1011   ASSERT_TRUE(fshader != NULL);
   1012   fshader->SetStatus(true, NULL, NULL);
   1013   static const GLuint kClientProgramId = 1234;
   1014   static const GLuint kServiceProgramId = 5679;
   1015   Program* program = manager_.CreateProgram(
   1016       kClientProgramId, kServiceProgramId);
   1017   ASSERT_TRUE(program != NULL);
   1018   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
   1019   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
   1020 
   1021   static const GLenum kSamplerTypes[] = {
   1022     GL_SAMPLER_2D,
   1023     GL_SAMPLER_CUBE,
   1024     GL_SAMPLER_EXTERNAL_OES,
   1025     GL_SAMPLER_3D_OES,
   1026     GL_SAMPLER_2D_RECT_ARB,
   1027   };
   1028   const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
   1029   for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
   1030     static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
   1031       { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
   1032       { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
   1033       { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
   1034     };
   1035     ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
   1036       { kUniform1Name,
   1037         kUniform1Size,
   1038         kUniform1Type,
   1039         kUniform1FakeLocation,
   1040         kUniform1RealLocation,
   1041         kUniform1DesiredLocation,
   1042         kUniform1Name,
   1043       },
   1044       { kUniform2Name,
   1045         kUniform2Size,
   1046         kSamplerTypes[ii],
   1047         kUniform2FakeLocation,
   1048         kUniform2RealLocation,
   1049         kUniform2DesiredLocation,
   1050         kUniform2Name,
   1051       },
   1052       { kUniform3BadName,
   1053         kUniform3Size,
   1054         kUniform3Type,
   1055         kUniform3FakeLocation,
   1056         kUniform3RealLocation,
   1057         kUniform3DesiredLocation,
   1058         kUniform3GoodName,
   1059       },
   1060     };
   1061     const size_t kNumAttribs = arraysize(kAttribs);
   1062     const size_t kNumUniforms = arraysize(kUniforms);
   1063     SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
   1064                 kServiceProgramId);
   1065     program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
   1066     SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
   1067     manager_.ClearUniforms(program);
   1068   }
   1069 }
   1070 
   1071 TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
   1072   const GLuint kVShaderClientId = 2001;
   1073   const GLuint kFShaderClientId = 2002;
   1074   const GLuint kVShaderServiceId = 3001;
   1075   const GLuint kFShaderServiceId = 3002;
   1076 
   1077   const GLint kUniform1DesiredLocation = 10;
   1078   const GLint kUniform2DesiredLocation = -1;
   1079   const GLint kUniform3DesiredLocation = 5;
   1080 
   1081   Shader* vshader = shader_manager_.CreateShader(
   1082       kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
   1083   ASSERT_TRUE(vshader != NULL);
   1084   vshader->SetStatus(true, NULL, NULL);
   1085   Shader* fshader = shader_manager_.CreateShader(
   1086       kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
   1087   ASSERT_TRUE(fshader != NULL);
   1088   fshader->SetStatus(true, NULL, NULL);
   1089   static const GLuint kClientProgramId = 1234;
   1090   static const GLuint kServiceProgramId = 5679;
   1091   Program* program = manager_.CreateProgram(
   1092       kClientProgramId, kServiceProgramId);
   1093   ASSERT_TRUE(program != NULL);
   1094   EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
   1095   EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
   1096   EXPECT_TRUE(program->SetUniformLocationBinding(
   1097       kUniform1Name, kUniform1DesiredLocation));
   1098   EXPECT_TRUE(program->SetUniformLocationBinding(
   1099       kUniform3BadName, kUniform3DesiredLocation));
   1100 
   1101   static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
   1102     { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
   1103     { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
   1104     { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
   1105   };
   1106   ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
   1107     { kUniform1Name,
   1108       kUniform1Size,
   1109       kUniform1Type,
   1110       kUniform1FakeLocation,
   1111       kUniform1RealLocation,
   1112       kUniform1DesiredLocation,
   1113       kUniform1Name,
   1114     },
   1115     { kUniform2Name,
   1116       kUniform2Size,
   1117       kUniform2Type,
   1118       kUniform2FakeLocation,
   1119       kUniform2RealLocation,
   1120       kUniform2DesiredLocation,
   1121       kUniform2Name,
   1122     },
   1123     { kUniform3BadName,
   1124       kUniform3Size,
   1125       kUniform3Type,
   1126       kUniform3FakeLocation,
   1127       kUniform3RealLocation,
   1128       kUniform3DesiredLocation,
   1129       kUniform3GoodName,
   1130     },
   1131   };
   1132 
   1133   const size_t kNumAttribs = arraysize(kAttribs);
   1134   const size_t kNumUniforms = arraysize(kUniforms);
   1135   SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
   1136               kServiceProgramId);
   1137   program->Link(NULL, NULL, NULL, NULL, base::Bind(&ShaderCacheCb));
   1138 
   1139   EXPECT_EQ(kUniform1DesiredLocation,
   1140             program->GetUniformFakeLocation(kUniform1Name));
   1141   EXPECT_EQ(kUniform3DesiredLocation,
   1142             program->GetUniformFakeLocation(kUniform3BadName));
   1143   EXPECT_EQ(kUniform3DesiredLocation,
   1144             program->GetUniformFakeLocation(kUniform3GoodName));
   1145 }
   1146 
   1147 class ProgramManagerWithCacheTest : public testing::Test {
   1148  public:
   1149   static const GLuint kClientProgramId = 1;
   1150   static const GLuint kServiceProgramId = 10;
   1151   static const GLuint kVertexShaderClientId = 2;
   1152   static const GLuint kFragmentShaderClientId = 20;
   1153   static const GLuint kVertexShaderServiceId = 3;
   1154   static const GLuint kFragmentShaderServiceId = 30;
   1155 
   1156   ProgramManagerWithCacheTest()
   1157       : cache_(new MockProgramCache()),
   1158         manager_(cache_.get()),
   1159         vertex_shader_(NULL),
   1160         fragment_shader_(NULL),
   1161         program_(NULL) {
   1162   }
   1163   virtual ~ProgramManagerWithCacheTest() {
   1164     manager_.Destroy(false);
   1165     shader_manager_.Destroy(false);
   1166   }
   1167 
   1168  protected:
   1169   virtual void SetUp() {
   1170     gl_.reset(new StrictMock<gfx::MockGLInterface>());
   1171     ::gfx::GLInterface::SetGLInterface(gl_.get());
   1172 
   1173     vertex_shader_ = shader_manager_.CreateShader(
   1174        kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
   1175     fragment_shader_ = shader_manager_.CreateShader(
   1176        kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
   1177     ASSERT_TRUE(vertex_shader_ != NULL);
   1178     ASSERT_TRUE(fragment_shader_ != NULL);
   1179     vertex_shader_->UpdateSource("lka asjf bjajsdfj");
   1180     fragment_shader_->UpdateSource("lka asjf a   fasgag 3rdsf3 bjajsdfj");
   1181 
   1182     program_ = manager_.CreateProgram(
   1183         kClientProgramId, kServiceProgramId);
   1184     ASSERT_TRUE(program_ != NULL);
   1185 
   1186     program_->AttachShader(&shader_manager_, vertex_shader_);
   1187     program_->AttachShader(&shader_manager_, fragment_shader_);
   1188   }
   1189 
   1190   virtual void TearDown() {
   1191     ::gfx::GLInterface::SetGLInterface(NULL);
   1192   }
   1193 
   1194   void SetShadersCompiled() {
   1195     vertex_shader_->SetStatus(true, NULL, NULL);
   1196     fragment_shader_->SetStatus(true, NULL, NULL);
   1197   }
   1198 
   1199   void SetProgramCached() {
   1200     cache_->LinkedProgramCacheSuccess(
   1201         vertex_shader_->source()->c_str(),
   1202         NULL,
   1203         fragment_shader_->source()->c_str(),
   1204         NULL,
   1205         &program_->bind_attrib_location_map());
   1206   }
   1207 
   1208   void SetExpectationsForProgramCached() {
   1209     SetExpectationsForProgramCached(program_,
   1210                                     vertex_shader_,
   1211                                     fragment_shader_);
   1212   }
   1213 
   1214   void SetExpectationsForProgramCached(
   1215       Program* program,
   1216       Shader* vertex_shader,
   1217       Shader* fragment_shader) {
   1218     EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
   1219         program->service_id(),
   1220         vertex_shader,
   1221         NULL,
   1222         fragment_shader,
   1223         NULL,
   1224         &program->bind_attrib_location_map(),
   1225         _)).Times(1);
   1226   }
   1227 
   1228   void SetExpectationsForNotCachingProgram() {
   1229     SetExpectationsForNotCachingProgram(program_,
   1230                                         vertex_shader_,
   1231                                         fragment_shader_);
   1232   }
   1233 
   1234   void SetExpectationsForNotCachingProgram(
   1235       Program* program,
   1236       Shader* vertex_shader,
   1237       Shader* fragment_shader) {
   1238     EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
   1239         program->service_id(),
   1240         vertex_shader,
   1241         NULL,
   1242         fragment_shader,
   1243         NULL,
   1244         &program->bind_attrib_location_map(),
   1245         _)).Times(0);
   1246   }
   1247 
   1248   void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
   1249     SetExpectationsForProgramLoad(kServiceProgramId,
   1250                                   program_,
   1251                                   vertex_shader_,
   1252                                   fragment_shader_,
   1253                                   result);
   1254   }
   1255 
   1256   void SetExpectationsForProgramLoad(
   1257       GLuint service_program_id,
   1258       Program* program,
   1259       Shader* vertex_shader,
   1260       Shader* fragment_shader,
   1261       ProgramCache::ProgramLoadResult result) {
   1262     EXPECT_CALL(*cache_.get(),
   1263                 LoadLinkedProgram(service_program_id,
   1264                                   vertex_shader,
   1265                                   NULL,
   1266                                   fragment_shader,
   1267                                   NULL,
   1268                                   &program->bind_attrib_location_map(),
   1269                                   _))
   1270         .WillOnce(Return(result));
   1271   }
   1272 
   1273   void SetExpectationsForProgramLoadSuccess() {
   1274     SetExpectationsForProgramLoadSuccess(kServiceProgramId);
   1275   }
   1276 
   1277   void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
   1278     TestHelper::SetupProgramSuccessExpectations(gl_.get(),
   1279                                                 NULL,
   1280                                                 0,
   1281                                                 NULL,
   1282                                                 0,
   1283                                                 service_program_id);
   1284   }
   1285 
   1286   void SetExpectationsForProgramLink() {
   1287     SetExpectationsForProgramLink(kServiceProgramId);
   1288   }
   1289 
   1290   void SetExpectationsForProgramLink(GLuint service_program_id) {
   1291     TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
   1292     if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
   1293       EXPECT_CALL(*gl_.get(),
   1294                   ProgramParameteri(service_program_id,
   1295                                     PROGRAM_BINARY_RETRIEVABLE_HINT,
   1296                                     GL_TRUE)).Times(1);
   1297     }
   1298   }
   1299 
   1300   void SetExpectationsForSuccessCompile(
   1301       const Shader* shader) {
   1302     const GLuint shader_id = shader->service_id();
   1303     const char* src = shader->source()->c_str();
   1304     EXPECT_CALL(*gl_.get(),
   1305                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
   1306     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
   1307     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
   1308       .WillOnce(SetArgumentPointee<2>(GL_TRUE));
   1309   }
   1310 
   1311   void SetExpectationsForNoCompile(const Shader* shader) {
   1312     const GLuint shader_id = shader->service_id();
   1313     const char* src = shader->source()->c_str();
   1314     EXPECT_CALL(*gl_.get(),
   1315                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
   1316     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
   1317     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
   1318         .Times(0);
   1319   }
   1320 
   1321   void SetExpectationsForErrorCompile(const Shader* shader) {
   1322     const GLuint shader_id = shader->service_id();
   1323     const char* src = shader->source()->c_str();
   1324     EXPECT_CALL(*gl_.get(),
   1325                 ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
   1326     EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
   1327     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
   1328       .WillOnce(SetArgumentPointee<2>(GL_FALSE));
   1329     EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
   1330       .WillOnce(SetArgumentPointee<2>(0));
   1331     EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
   1332       .Times(1);
   1333   }
   1334 
   1335   scoped_ptr<StrictMock<gfx::MockGLInterface> > gl_;
   1336 
   1337   scoped_ptr<MockProgramCache> cache_;
   1338   ProgramManager manager_;
   1339 
   1340   Shader* vertex_shader_;
   1341   Shader* fragment_shader_;
   1342   Program* program_;
   1343   ShaderManager shader_manager_;
   1344 };
   1345 
   1346 // GCC requires these declarations, but MSVC requires they not be present
   1347 #ifndef COMPILER_MSVC
   1348 const GLuint ProgramManagerWithCacheTest::kClientProgramId;
   1349 const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
   1350 const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
   1351 const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
   1352 const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
   1353 const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
   1354 #endif
   1355 
   1356 TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
   1357   SetShadersCompiled();
   1358   SetExpectationsForProgramLink();
   1359   SetExpectationsForProgramCached();
   1360   EXPECT_TRUE(program_->Link(NULL, NULL, NULL, NULL,
   1361                              base::Bind(&ShaderCacheCb)));
   1362 }
   1363 
   1364 TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
   1365   SetShadersCompiled();
   1366   SetProgramCached();
   1367 
   1368   SetExpectationsForNoCompile(vertex_shader_);
   1369   SetExpectationsForNoCompile(fragment_shader_);
   1370   SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
   1371   SetExpectationsForNotCachingProgram();
   1372   SetExpectationsForProgramLoadSuccess();
   1373 
   1374   EXPECT_TRUE(program_->Link(NULL, NULL, NULL, NULL,
   1375                              base::Bind(&ShaderCacheCb)));
   1376 }
   1377 
   1378 }  // namespace gles2
   1379 }  // namespace gpu
   1380