15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/program_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_format.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/common_decoder.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/feature_info.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_service_test.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mocks.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/shader_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/test_helper.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gl/gl_mock.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::DoAll;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::MatcherCast;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Pointee;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Return;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::ReturnRef;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SetArrayArgument;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::SetArgumentPointee;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrEq;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const uint32 kMaxVaryingVectors = 8;
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShaderCacheCb(const std::string& key, const std::string& shader) {}
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace anonymous
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ProgramManagerTest : public GpuServiceTest {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ProgramManagerTest() : manager_(NULL, kMaxVaryingVectors) { }
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ProgramManagerTest() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager_.Destroy(false);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManager manager_;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerTest, Basic) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient1Id = 1;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kService1Id = 11;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient2Id = 2;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can create program.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.CreateProgram(kClient1Id, kService1Id);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check program got created.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program1 = manager_.GetProgram(kClient1Id);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program1 != NULL);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLuint client_id = 0;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(manager_.GetClientId(program1->service_id(), &client_id));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kClient1Id, client_id);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we get nothing for a non-existent program.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(manager_.GetProgram(kClient2Id) == NULL);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerTest, Destroy) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient1Id = 1;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kService1Id = 11;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can create program.
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program0 = manager_.CreateProgram(kClient1Id, kService1Id);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program0 != NULL);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check program got created.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program1 = manager_.GetProgram(kClient1Id);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(program0, program1);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*gl_, DeleteProgram(kService1Id))
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager_.Destroy(true);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the resources were released.
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program1 = manager_.GetProgram(kClient1Id);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program1 == NULL);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerTest, DeleteBug) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderManager shader_manager;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient1Id = 1;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient2Id = 2;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kService1Id = 11;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kService2Id = 12;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can create program.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Program> program1(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager_.CreateProgram(kClient1Id, kService1Id));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<Program> program2(
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager_.CreateProgram(kClient2Id, kService2Id));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check program got created.
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(program1.get());
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(program2.get());
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manager_.UseProgram(program1.get());
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manager_.MarkAsDeleted(&shader_manager, program1.get());
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  Program will be deleted when last ref is released.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*gl_, DeleteProgram(kService2Id))
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  manager_.MarkAsDeleted(&shader_manager, program2.get());
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(manager_.IsOwned(program1.get()));
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(manager_.IsOwned(program2.get()));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ProgramManagerTest, Program) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClient1Id = 1;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kService1Id = 11;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can create program.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program1 = manager_.CreateProgram(
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClient1Id, kService1Id);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program1);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kService1Id, program1->service_id());
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program1->InUse());
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program1->IsValid());
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program1->IsDeleted());
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program1->CanLink());
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program1->log_info() == NULL);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ProgramManagerWithShaderTest : public GpuServiceTest {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManagerWithShaderTest()
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      :  manager_(NULL, kMaxVaryingVectors), program_(NULL) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ProgramManagerWithShaderTest() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager_.Destroy(false);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shader_manager_.Destroy(false);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kNumVertexAttribs = 16;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 123;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 456;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kVertexShaderClientId = 201;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kFragmentShaderClientId = 202;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kVertexShaderServiceId = 301;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kFragmentShaderServiceId = 302;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kAttrib1Name;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kAttrib2Name;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kAttrib3Name;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib1Size = 1;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib2Size = 1;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib3Size = 1;
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kAttrib1Precision = SH_PRECISION_MEDIUMP;
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kAttrib2Precision = SH_PRECISION_HIGHP;
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kAttrib3Precision = SH_PRECISION_LOWP;
157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const int kAttribStaticUse = 0;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib1Location = 0;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib2Location = 1;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kAttrib3Location = 2;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kAttrib1Type = GL_FLOAT_VEC4;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kAttrib2Type = GL_FLOAT_VEC2;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kAttrib3Type = GL_FLOAT_VEC3;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kInvalidAttribLocation = 30;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kBadAttribIndex = kNumVertexAttribs;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform1Name;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform2Name;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform3BadName;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform3GoodName;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform1Size = 1;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform2Size = 3;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform3Size = 2;
1743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kUniform1Precision = SH_PRECISION_LOWP;
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kUniform2Precision = SH_PRECISION_MEDIUMP;
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const int kUniform3Precision = SH_PRECISION_HIGHP;
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const int kUniform1StaticUse = 1;
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const int kUniform2StaticUse = 1;
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const int kUniform3StaticUse = 1;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform1FakeLocation = 0;  // These are hard coded
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform2FakeLocation = 1;  // to match
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform3FakeLocation = 2;  // ProgramManager.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform1RealLocation = 11;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform2RealLocation = 22;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform3RealLocation = 33;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform1DesiredLocation = -1;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform2DesiredLocation = -1;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform3DesiredLocation = -1;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kUniform1Type = GL_FLOAT_VEC4;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kUniform2Type = GL_INT_VEC2;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kUniform3Type = GL_FLOAT_VEC3;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kInvalidUniformLocation = 30;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kBadUniformIndex = 1000;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kNumAttribs;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kNumUniforms;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef TestHelper::AttribInfo AttribInfo;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef TestHelper::UniformInfo UniformInfo;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef enum {
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    kVarUniform,
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    kVarVarying,
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    kVarAttribute
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } VarCategory;
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  typedef struct {
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int type;
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int size;
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int precision;
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int static_use;
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    std::string name;
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    VarCategory category;
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } VarInfo;
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    GpuServiceTest::SetUp();
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupDefaultShaderExpectations();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Shader* vertex_shader = shader_manager_.CreateShader(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Shader* fragment_shader =
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        shader_manager_.CreateShader(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            kFragmentShaderClientId, kFragmentShaderServiceId,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GL_FRAGMENT_SHADER);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(vertex_shader != NULL);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(fragment_shader != NULL);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vertex_shader->SetStatus(true, NULL, NULL);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fragment_shader->SetStatus(true, NULL, NULL);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_ = manager_.CreateProgram(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kClientProgramId, kServiceProgramId);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(program_ != NULL);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_->AttachShader(&shader_manager_, vertex_shader);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_->AttachShader(&shader_manager_, fragment_shader);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    program_->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Bind(&ShaderCacheCb));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupShader(AttribInfo* attribs, size_t num_attribs,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   UniformInfo* uniforms, size_t num_uniforms,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   GLuint service_id) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestHelper::SetupShader(
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gl_.get(), attribs, num_attribs, uniforms, num_uniforms, service_id);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupDefaultShaderExpectations() {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                kServiceProgramId);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupExpectationsForClearingUniforms(
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UniformInfo* uniforms, size_t num_uniforms) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestHelper::SetupExpectationsForClearingUniforms(
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gl_.get(), uniforms, num_uniforms);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return true if link status matches expected_link_status
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool LinkAsExpected(Program* program,
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      bool expected_link_status) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GLuint service_id = program->service_id();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expected_link_status) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  service_id);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::Bind(&ShaderCacheCb));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLint link_status;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program->GetProgramiv(GL_LINK_STATUS, &link_status);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (static_cast<bool>(link_status) == expected_link_status);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* SetupShaderVariableTest(const VarInfo* vertex_variables,
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   size_t vertex_variable_size,
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   const VarInfo* fragment_variables,
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                   size_t fragment_variable_size) {
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Set up shader
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kVShaderClientId = 1;
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kVShaderServiceId = 11;
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kFShaderClientId = 2;
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kFShaderServiceId = 12;
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    MockShaderTranslator vertex_shader_translator;
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap vertex_attrib_map;
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap vertex_uniform_map;
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap vertex_varying_map;
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t ii = 0; ii < vertex_variable_size; ++ii) {
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ShaderTranslator::VariableMap* map = NULL;
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      switch (vertex_variables[ii].category) {
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarAttribute:
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &vertex_attrib_map;
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarUniform:
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &vertex_uniform_map;
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarVarying:
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &vertex_varying_map;
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        default:
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          NOTREACHED();
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      (*map)[vertex_variables[ii].name] =
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          ShaderTranslator::VariableInfo(vertex_variables[ii].type,
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         vertex_variables[ii].size,
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         vertex_variables[ii].precision,
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         vertex_variables[ii].static_use,
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         vertex_variables[ii].name);
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::NameMap vertex_name_map;
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(vertex_shader_translator, attrib_map())
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(vertex_attrib_map));
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(vertex_shader_translator, uniform_map())
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(vertex_uniform_map));
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(vertex_shader_translator, varying_map())
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(vertex_varying_map));
319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(vertex_shader_translator, name_map())
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      .WillRepeatedly(ReturnRef(vertex_name_map));
321424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    MockShaderTranslator frag_shader_translator;
323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap frag_attrib_map;
324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap frag_uniform_map;
325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::VariableMap frag_varying_map;
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (size_t ii = 0; ii < fragment_variable_size; ++ii) {
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ShaderTranslator::VariableMap* map = NULL;
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      switch (fragment_variables[ii].category) {
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarAttribute:
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &frag_attrib_map;
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarUniform:
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &frag_uniform_map;
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        case kVarVarying:
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          map = &frag_varying_map;
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          break;
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        default:
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          NOTREACHED();
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      (*map)[fragment_variables[ii].name] =
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          ShaderTranslator::VariableInfo(fragment_variables[ii].type,
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         fragment_variables[ii].size,
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         fragment_variables[ii].precision,
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         fragment_variables[ii].static_use,
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                         fragment_variables[ii].name);
347424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
348424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ShaderTranslator::NameMap frag_name_map;
349424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(frag_shader_translator, attrib_map())
350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(frag_attrib_map));
351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(frag_shader_translator, uniform_map())
352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(frag_uniform_map));
353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(frag_shader_translator, varying_map())
354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        .WillRepeatedly(ReturnRef(frag_varying_map));
355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_CALL(frag_shader_translator, name_map())
356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      .WillRepeatedly(ReturnRef(frag_name_map));
357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Check we can create shader.
359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Shader* vshader = shader_manager_.CreateShader(
360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Shader* fshader = shader_manager_.CreateShader(
362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Check shader got created.
364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(vshader != NULL && fshader != NULL);
365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Set Status
366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    vshader->SetStatus(true, "", &vertex_shader_translator);
367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    fshader->SetStatus(true, "", &frag_shader_translator);
368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Set up program
370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kClientProgramId = 6666;
371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const GLuint kServiceProgramId = 8888;
372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    Program* program =
373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        manager_.CreateProgram(kClientProgramId, kServiceProgramId);
374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(program != NULL);
375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return program;
378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static AttribInfo kAttribs[];
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static UniformInfo kUniforms[];
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManager manager_;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program_;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderManager shader_manager_;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProgramManagerWithShaderTest::AttribInfo
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProgramManagerWithShaderTest::kAttribs[] = {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GCC requires these declarations, but MSVC requires they not be present
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef COMPILER_MSVC
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kNumVertexAttribs;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kClientProgramId;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kServiceProgramId;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kVertexShaderClientId;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kFragmentShaderClientId;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kVertexShaderServiceId;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithShaderTest::kFragmentShaderServiceId;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib1Size;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib2Size;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib3Size;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib1Location;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib2Location;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kAttrib3Location;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kAttrib1Type;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kAttrib2Type;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kAttrib3Type;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kInvalidAttribLocation;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kBadAttribIndex;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform1Size;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform2Size;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform3Size;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform1FakeLocation;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform2FakeLocation;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform3FakeLocation;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform1RealLocation;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform2RealLocation;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform3RealLocation;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform1DesiredLocation;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform2DesiredLocation;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kUniform3DesiredLocation;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kUniform1Type;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kUniform2Type;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLenum ProgramManagerWithShaderTest::kUniform3Type;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kInvalidUniformLocation;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLint ProgramManagerWithShaderTest::kBadUniformIndex;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t ProgramManagerWithShaderTest::kNumAttribs =
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arraysize(ProgramManagerWithShaderTest::kAttribs);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProgramManagerWithShaderTest::UniformInfo
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProgramManagerWithShaderTest::kUniforms[] = {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kUniform1Name,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1Size,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1Type,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1FakeLocation,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1RealLocation,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1DesiredLocation,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform1Name,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kUniform2Name,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2Size,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2Type,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2FakeLocation,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2RealLocation,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2DesiredLocation,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform2Name,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { kUniform3BadName,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3Size,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3Type,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3FakeLocation,
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3RealLocation,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3DesiredLocation,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUniform3GoodName,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  },
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t ProgramManagerWithShaderTest::kNumUniforms =
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    arraysize(ProgramManagerWithShaderTest::kUniforms);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kAttrib1Name = "attrib1";
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kAttrib2Name = "attrib2";
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kAttrib3Name = "attrib3";
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kUniform1Name = "uniform1";
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Correctly has array spec.
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kUniform2Name = "uniform2[0]";
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incorrectly missing array spec.
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kUniform3BadName = "uniform3";
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* ProgramManagerWithShaderTest::kUniform3GoodName = "uniform3[0]";
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetAttribInfos) {
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program::AttribInfoVector& infos =
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program->GetAttribInfos();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(kNumAttribs, infos.size());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < kNumAttribs; ++ii) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Program::VertexAttrib& info = infos[ii];
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AttribInfo& expected = kAttribs[ii];
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.size, info.size);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.type, info.type);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.location, info.location);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ(expected.name, info.name.c_str());
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetAttribInfo) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kValidIndex = 1;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kInvalidIndex = 1000;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program::VertexAttrib* info =
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program->GetAttribInfo(kValidIndex);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kAttrib2Size, info->size);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kAttrib2Type, info->type);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kAttrib2Location, info->location);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ(kAttrib2Name, info->name.c_str());
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->GetAttribInfo(kInvalidIndex) == NULL);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetAttribLocation) {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kInvalidName = "foo";
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(kAttrib2Location, program->GetAttribLocation(kAttrib2Name));
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, program->GetAttribLocation(kInvalidName));
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetUniformInfo) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kInvalidIndex = 1000;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program::UniformInfo* info =
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      program->GetUniformInfo(0);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform1Size, info->size);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform1Type, info->type);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform1RealLocation, info->element_locations[0]);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ(kUniform1Name, info->name.c_str());
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info = program->GetUniformInfo(1);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2Size, info->size);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2Type, info->type);
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2RealLocation, info->element_locations[0]);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ(kUniform2Name, info->name.c_str());
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info = program->GetUniformInfo(2);
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We emulate certain OpenGL drivers by supplying the name without
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the array spec. Our implementation should correctly add the required spec.
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3Size, info->size);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3Type, info->type);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3RealLocation, info->element_locations[0]);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_STREQ(kUniform3GoodName, info->name.c_str());
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->GetUniformInfo(kInvalidIndex) == NULL);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, AttachDetachShader) {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 124;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 457;
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->DetachShader(&shader_manager_, vshader);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->DetachShader(&shader_manager_, fshader);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->AttachShader(&shader_manager_, vshader));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(false, "", NULL);
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(false, "", NULL);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->DetachShader(&shader_manager_, fshader));
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->DetachShader(&shader_manager_, fshader));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetUniformFakeLocation) {
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
5931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Emulate the situation that uniform3[1] isn't used and optimized out by
5941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // a driver, so it's location is -1.
5951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
5961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      program->GetUniformInfo(2));
5971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(uniform != NULL && kUniform3Size == 2);
5981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(kUniform3Size, uniform->size);
5991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  uniform->element_locations[1] = -1;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform1FakeLocation,
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform1Name));
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2FakeLocation,
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform2Name));
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3FakeLocation,
6051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            program->GetUniformFakeLocation(kUniform3BadName));
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can get uniform2 as "uniform2" even though the name is
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "uniform2[0]"
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2FakeLocation,
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation("uniform2"));
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can get uniform3 as "uniform3[0]" even though we simulated GL
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returning "uniform3"
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3FakeLocation,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform3GoodName));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we can get the locations of the array elements > 1
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 1),
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation("uniform2[1]"));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProgramManager::MakeFakeLocation(kUniform2FakeLocation, 2),
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation("uniform2[2]"));
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform2[3]"));
6201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[1]"));
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(-1, program->GetUniformFakeLocation("uniform3[2]"));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GetUniformInfoByFakeLocation) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kInvalidLocation = 1234;
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program::UniformInfo* info;
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint real_location = -1;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint array_index = -1;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info = program->GetUniformInfoByFakeLocation(
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2FakeLocation, &real_location, &array_index);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2RealLocation, real_location);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, array_index);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2Type, info->type);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  real_location = -1;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  array_index = -1;
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info = program->GetUniformInfoByFakeLocation(
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kInvalidLocation, &real_location, &array_index);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info == NULL);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, real_location);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, array_index);
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GLint loc = program->GetUniformFakeLocation("uniform2[2]");
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info = program->GetUniformInfoByFakeLocation(
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loc, &real_location, &array_index);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(info != NULL);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2RealLocation + 2 * 2, real_location);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, array_index);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some GL drivers incorrectly return gl_DepthRange and possibly other uniforms
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that start with "gl_". Our implementation catches these and does not allow
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// them back to client.
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsGLUnderscoreUniform) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform2Name = "gl_longNameWeCanCheckFor";
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform1Name,
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Size,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Type,
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1FakeLocation,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1RealLocation,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1DesiredLocation,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Name,
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform2Name,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Size,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Type,
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2FakeLocation,
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2RealLocation,
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2DesiredLocation,
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Name,
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform3BadName,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Size,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Type,
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3FakeLocation,
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3RealLocation,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3DesiredLocation,
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3GoodName,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumUniforms = arraysize(kUniforms);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1234;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 5679;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupShader(
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program =
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager_.CreateProgram(kClientProgramId, kServiceProgramId);
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&ShaderCacheCb));
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GLint value = 0;
7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->GetProgramiv(GL_ACTIVE_ATTRIBUTES, &value);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, value);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we skipped the "gl_" uniform.
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->GetProgramiv(GL_ACTIVE_UNIFORMS, &value);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, value);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that our max length adds room for the array spec and is not as long
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as the "gl_" uniform we skipped.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // +4u is to account for "gl_" and NULL terminator.
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->GetProgramiv(GL_ACTIVE_UNIFORM_MAX_LENGTH, &value);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(strlen(kUniform3BadName) + 4u, static_cast<size_t>(value));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the bug comparing similar array names is fixed.
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, SimilarArrayNames) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform2Name = "u_nameLong[0]";
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* kUniform3Name = "u_name[0]";
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform2Size = 2;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLint kUniform3Size = 2;
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform1Name,
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Size,
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Type,
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1FakeLocation,
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1RealLocation,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1DesiredLocation,
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Name,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform2Name,
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Size,
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Type,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2FakeLocation,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2RealLocation,
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2DesiredLocation,
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Name,
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform3Name,
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Size,
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Type,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3FakeLocation,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3RealLocation,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3DesiredLocation,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Name,
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumUniforms = arraysize(kUniforms);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1234;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 5679;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupShader(
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAttribs, kNumAttribs, kUniforms, kNumUniforms, kServiceProgramId);
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program =
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager_.CreateProgram(kClientProgramId, kServiceProgramId);
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&ShaderCacheCb));
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we get the correct locations.
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform2FakeLocation,
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform2Name));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3FakeLocation,
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform3Name));
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some GL drivers incorrectly return the wrong type. For example they return
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GL_FLOAT_VEC2 when they should return GL_FLOAT_MAT2. Check we handle this.
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, GLDriverReturnsWrongTypeInfo) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GLenum kAttrib2BadType = GL_FLOAT_VEC2;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GLenum kAttrib2GoodType = GL_FLOAT_MAT2;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GLenum kUniform2BadType = GL_FLOAT_VEC3;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GLenum kUniform2GoodType = GL_FLOAT_MAT3;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockShaderTranslator shader_translator;
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderTranslator::VariableMap attrib_map;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderTranslator::VariableMap uniform_map;
7943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap varying_map;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrib_map[kAttrib1Name] = ShaderTranslatorInterface::VariableInfo(
796424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttrib1Type, kAttrib1Size, kAttrib1Precision,
797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttribStaticUse, kAttrib1Name);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrib_map[kAttrib2Name] = ShaderTranslatorInterface::VariableInfo(
799424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttrib2GoodType, kAttrib2Size, kAttrib2Precision,
800424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttribStaticUse, kAttrib2Name);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrib_map[kAttrib3Name] = ShaderTranslatorInterface::VariableInfo(
802424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttrib3Type, kAttrib3Size, kAttrib3Precision,
803424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kAttribStaticUse, kAttrib3Name);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uniform_map[kUniform1Name] = ShaderTranslatorInterface::VariableInfo(
805424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform1Type, kUniform1Size, kUniform1Precision,
806424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform1StaticUse, kUniform1Name);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uniform_map[kUniform2Name] = ShaderTranslatorInterface::VariableInfo(
808424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform2GoodType, kUniform2Size, kUniform2Precision,
809424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform2StaticUse, kUniform2Name);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uniform_map[kUniform3GoodName] = ShaderTranslatorInterface::VariableInfo(
811424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform3Type, kUniform3Size, kUniform3Precision,
812424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kUniform3StaticUse, kUniform3GoodName);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(shader_translator, attrib_map())
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(ReturnRef(attrib_map));
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(shader_translator, uniform_map())
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(ReturnRef(uniform_map));
8173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(shader_translator, varying_map())
8183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(varying_map));
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShaderTranslator::NameMap name_map;
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(shader_translator, name_map())
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(ReturnRef(name_map));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", &shader_translator);
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", &shader_translator);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib2Name, kAttrib2Size, kAttrib2BadType, kAttrib2Location, },
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform1Name,
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Size,
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Type,
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1FakeLocation,
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1RealLocation,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1DesiredLocation,
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Name,
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform2Name,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Size,
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2BadType,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2FakeLocation,
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2RealLocation,
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2DesiredLocation,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Name,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform3BadName,
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Size,
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Type,
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3FakeLocation,
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3RealLocation,
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3DesiredLocation,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3GoodName,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumAttribs= arraysize(kAttribs);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumUniforms = arraysize(kUniforms);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1234;
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 5679;
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              kServiceProgramId);
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program!= NULL);
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&ShaderCacheCb));
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that we got the good type, not the bad.
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check Attribs
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned index = 0; index < kNumAttribs; ++index) {
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Program::VertexAttrib* attrib_info =
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->GetAttribInfo(index);
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(attrib_info != NULL);
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShaderTranslator::VariableMap::const_iterator it = attrib_map.find(
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        attrib_info->name);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(it != attrib_map.end());
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->first, attrib_info->name);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(it->second.type), attrib_info->type);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.size, attrib_info->size);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.name, attrib_info->name);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check Uniforms
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (unsigned index = 0; index < kNumUniforms; ++index) {
8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Program::UniformInfo* uniform_info =
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->GetUniformInfo(index);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(uniform_info != NULL);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShaderTranslator::VariableMap::const_iterator it = uniform_map.find(
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        uniform_info->name);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(it != uniform_map.end());
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->first, uniform_info->name);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(static_cast<GLenum>(it->second.type), uniform_info->type);
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.size, uniform_info->size);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.name, uniform_info->name);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount) {
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 124;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 457;
9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(vshader->InUse());
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fshader->InUse());
9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(vshader->InUse());
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fshader->InUse());
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->InUse());
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->IsDeleted());
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UseProgram(program);
9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UseProgram(program);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.MarkAsDeleted(&shader_manager_, program);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->IsDeleted());
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info2 = manager_.GetProgram(kClientProgramId);
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(program, info2);
9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UnuseProgram(&shader_manager_, program);
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this should delete the info.
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UnuseProgram(&shader_manager_, program);
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info2 = manager_.GetProgram(kClientProgramId);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2 == NULL);
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(vshader->InUse());
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fshader->InUse());
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, ProgramInfoUseCount2) {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 124;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 457;
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->CanLink());
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", NULL);
9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(vshader->InUse());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fshader->InUse());
9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(vshader->InUse());
9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(fshader->InUse());
9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->CanLink());
9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->InUse());
9832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->IsDeleted());
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UseProgram(program);
9852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UseProgram(program);
9872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UnuseProgram(&shader_manager_, program);
9892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->InUse());
9902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.UnuseProgram(&shader_manager_, program);
9912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->InUse());
9922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* info2 = manager_.GetProgram(kClientProgramId);
9932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(program, info2);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this should delete the program.
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*gl_, DeleteProgram(kServiceProgramId))
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .RetiresOnSaturation();
9982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  manager_.MarkAsDeleted(&shader_manager_, program);
9992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  info2 = manager_.GetProgram(kClientProgramId);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(info2 == NULL);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(vshader->InUse());
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fshader->InUse());
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, ProgramInfoGetProgramInfo) {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommonDecoder::Bucket bucket;
10072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
10092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->GetProgramInfo(&manager_, &bucket);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramInfoHeader* header =
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(header != NULL);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, header->link_status);
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(*header),
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(inputs != NULL);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProgramInput* input = inputs;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gman): Don't assume these are in order.
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < header->num_attribs; ++ii) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const AttribInfo& expected = kAttribs[ii];
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.size, input->size);
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.type, input->type);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int32* location = bucket.GetDataAs<const int32*>(
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        input->location_offset, sizeof(int32));
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(location != NULL);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.location, *location);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* name_buf = bucket.GetDataAs<const char*>(
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        input->name_offset, input->name_length);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(name_buf != NULL);
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(name_buf, input->name_length);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ(expected.name, name.c_str());
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++input;
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gman): Don't assume these are in order.
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const UniformInfo& expected = kUniforms[ii];
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.size, input->size);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected.type, input->type);
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int32* locations = bucket.GetDataAs<const int32*>(
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        input->location_offset, sizeof(int32) * input->size);
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(locations != NULL);
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int32 jj = 0; jj < input->size; ++jj) {
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProgramManager::MakeFakeLocation(expected.fake_location, jj),
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          locations[jj]);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* name_buf = bucket.GetDataAs<const char*>(
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        input->name_offset, input->name_length);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(name_buf != NULL);
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string name(name_buf, input->name_length);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_STREQ(expected.good_name, name.c_str());
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++input;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(header->num_attribs + header->num_uniforms,
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            static_cast<uint32>(input - inputs));
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Some drivers optimize out unused uniform array elements, so their
10621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// location would be -1.
10631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, UnusedUniformArrayElements) {
10641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  CommonDecoder::Bucket bucket;
10651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const Program* program = manager_.GetProgram(kClientProgramId);
10661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(program != NULL);
10671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Emulate the situation that only the first element has a valid location.
10681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // TODO(zmo): Don't assume these are in order.
10691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t ii = 0; ii < arraysize(kUniforms); ++ii) {
10701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    Program::UniformInfo* uniform = const_cast<Program::UniformInfo*>(
10711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        program->GetUniformInfo(ii));
10721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ASSERT_TRUE(uniform != NULL);
10731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(static_cast<size_t>(kUniforms[ii].size),
10741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              uniform->element_locations.size());
10751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (GLsizei jj = 1; jj < uniform->size; ++jj)
10761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      uniform->element_locations[jj] = -1;
10771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
10781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  program->GetProgramInfo(&manager_, &bucket);
10791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ProgramInfoHeader* header =
10801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      bucket.GetDataAs<ProgramInfoHeader*>(0, sizeof(ProgramInfoHeader));
10811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(header != NULL);
10821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(1u, header->link_status);
10831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(arraysize(kAttribs), header->num_attribs);
10841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(arraysize(kUniforms), header->num_uniforms);
10851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const ProgramInput* inputs = bucket.GetDataAs<const ProgramInput*>(
10861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      sizeof(*header),
10871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      sizeof(ProgramInput) * (header->num_attribs + header->num_uniforms));
10881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  ASSERT_TRUE(inputs != NULL);
10891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const ProgramInput* input = inputs + header->num_attribs;
10901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (uint32 ii = 0; ii < header->num_uniforms; ++ii) {
10911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const UniformInfo& expected = kUniforms[ii];
10921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(expected.size, input->size);
10931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const int32* locations = bucket.GetDataAs<const int32*>(
10941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        input->location_offset, sizeof(int32) * input->size);
10951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ASSERT_TRUE(locations != NULL);
10961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    EXPECT_EQ(
10971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        ProgramManager::MakeFakeLocation(expected.fake_location, 0),
10981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        locations[0]);
10991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    for (int32 jj = 1; jj < input->size; ++jj)
11001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      EXPECT_EQ(-1, locations[jj]);
11011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ++input;
11021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
11031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
11041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, BindAttribLocationConflicts) {
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up shader
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 1;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 11;
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 12;
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockShaderTranslator shader_translator;
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderTranslator::VariableMap attrib_map;
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32 ii = 0; ii < kNumAttribs; ++ii) {
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attrib_map[kAttribs[ii].name] = ShaderTranslatorInterface::VariableInfo(
11153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        kAttribs[ii].type,
11163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        kAttribs[ii].size,
11173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        SH_PRECISION_MEDIUMP,
1118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        kAttribStaticUse,
11193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        kAttribs[ii].name);
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderTranslator::VariableMap uniform_map;
11223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap varying_map;
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(shader_translator, attrib_map())
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(ReturnRef(attrib_map));
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(shader_translator, uniform_map())
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(ReturnRef(uniform_map));
11273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(shader_translator, varying_map())
11283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(varying_map));
11292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShaderTranslator::NameMap name_map;
11302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(shader_translator, name_map())
11312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(ReturnRef(name_map));
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check we can create shader.
11332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
11352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check shader got created.
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL && fshader != NULL);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set Status
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, "", &shader_translator);
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check attrib infos got copied.
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ShaderTranslator::VariableMap::const_iterator it = attrib_map.begin();
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != attrib_map.end(); ++it) {
11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Shader::VariableInfo* variable_info =
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vshader->GetAttribInfo(it->first);
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(variable_info != NULL);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.type, variable_info->type);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.size, variable_info->size);
11493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_EQ(it->second.precision, variable_info->precision);
1150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    EXPECT_EQ(it->second.static_use, variable_info->static_use);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(it->second.name, variable_info->name);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, "", NULL);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up program
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kClientProgramId = 6666;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kServiceProgramId = 8888;
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program =
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      manager_.CreateProgram(kClientProgramId, kServiceProgramId);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->SetAttribLocationBinding(kAttrib1Name, 0);
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
11702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->SetAttribLocationBinding("xxx", 0);
11722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
11732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->SetAttribLocationBinding(kAttrib2Name, 1);
11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(program->DetectAttribLocationBindingConflicts());
11772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  program->SetAttribLocationBinding(kAttrib2Name, 0);
11802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->DetectAttribLocationBindingConflicts());
11812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, UniformsPrecisionMismatch) {
11853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up shader
11863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kVShaderClientId = 1;
11873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kVShaderServiceId = 11;
11883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kFShaderClientId = 2;
11893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kFShaderServiceId = 12;
11903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
11913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockShaderTranslator vertex_shader_translator;
11923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap vertex_attrib_map;
11933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap vertex_uniform_map;
11943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  vertex_uniform_map["a"] = ShaderTranslator::VariableInfo(
1195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      1, 3, SH_PRECISION_MEDIUMP, 1, "a");
11963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap vertex_varying_map;
11973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::NameMap vertex_name_map;
11983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(vertex_shader_translator, attrib_map())
11993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(vertex_attrib_map));
12003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(vertex_shader_translator, uniform_map())
12013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(vertex_uniform_map));
12023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(vertex_shader_translator, varying_map())
12033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(vertex_varying_map));
12043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(vertex_shader_translator, name_map())
12053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    .WillRepeatedly(ReturnRef(vertex_name_map));
12063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockShaderTranslator frag_shader_translator;
12083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap frag_attrib_map;
12093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap frag_uniform_map;
12103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  frag_uniform_map["a"] = ShaderTranslator::VariableInfo(
1211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      1, 3, SH_PRECISION_LOWP, 1, "a");
12123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::VariableMap frag_varying_map;
12133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ShaderTranslator::NameMap frag_name_map;
12143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(frag_shader_translator, attrib_map())
12153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(frag_attrib_map));
12163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(frag_shader_translator, uniform_map())
12173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(frag_uniform_map));
12183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(frag_shader_translator, varying_map())
12193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      .WillRepeatedly(ReturnRef(frag_varying_map));
12203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(frag_shader_translator, name_map())
12213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    .WillRepeatedly(ReturnRef(frag_name_map));
12223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Check we can create shader.
12243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
12253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
12263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
12273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
12283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Check shader got created.
12293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL && fshader != NULL);
12303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set Status
12313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  vshader->SetStatus(true, "", &vertex_shader_translator);
12323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  fshader->SetStatus(true, "", &frag_shader_translator);
12333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up program
12353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kClientProgramId = 6666;
12363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const GLuint kServiceProgramId = 8888;
12373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Program* program =
12383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      manager_.CreateProgram(kClientProgramId, kServiceProgramId);
12393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(program != NULL);
12403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
12413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
12423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program->DetectUniformsMismatch(&conflicting_name));
12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("a", conflicting_name);
12473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
12483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
12493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// If a varying has different type in the vertex and fragment
1251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// shader, linking should fail.
1252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, VaryingTypeMismatch) {
125358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexVarying =
125458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC3, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
125558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVarying =
125658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
125758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
125858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &kVertexVarying, 1, &kFragmentVarying, 1);
1259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("a", conflicting_name);
1264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
1265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// If a varying has different array size in the vertex and fragment
1268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// shader, linking should fail.
1269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, VaryingArraySizeMismatch) {
127058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexVarying =
127158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
127258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVarying =
127358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
127458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
127558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &kVertexVarying, 1, &kFragmentVarying, 1);
1276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
12785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
12805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("a", conflicting_name);
1281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
1282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// If a varying has different precision in the vertex and fragment
1285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// shader, linking should succeed.
1286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, VaryingPrecisionMismatch) {
128758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexVarying =
128858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 2, SH_PRECISION_HIGHP, 1, "a", kVarVarying };
128958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVarying =
129058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 2, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
129158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
129258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &kVertexVarying, 1, &kFragmentVarying, 1);
1293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(conflicting_name.empty());
1298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
1299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// If a varying is statically used in fragment shader but not
1302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// declared in vertex shader, link should fail.
1303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, VaryingMissing) {
130458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVarying =
130558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 3, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying };
130658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
130758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      NULL, 0, &kFragmentVarying, 1);
1308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program->DetectVaryingsMismatch(&conflicting_name));
13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("a", conflicting_name);
1313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
1314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// If a varying is declared but not statically used in fragment
1317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// shader, even if it's not declared in vertex shader, link should
1318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// succeed.
1319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, InactiveVarying) {
132058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVarying =
132158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT, 3, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying };
132258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
132358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      NULL, 0, &kFragmentVarying, 1);
1324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(program->DetectVaryingsMismatch(&conflicting_name));
13285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(conflicting_name.empty());
1329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
1330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
1331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
133258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Uniforms and attributes are both global variables, thus sharing
133358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// the same namespace. Any name conflicts should cause link
133458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// failure.
133558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, AttribUniformNameConflict) {
133658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexAttribute =
133758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarAttribute };
133858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentUniform =
133958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 1, SH_PRECISION_MEDIUMP, 1, "a", kVarUniform };
134058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
134158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      &kVertexAttribute, 1, &kFragmentUniform, 1);
134258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string conflicting_name;
13445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program->DetectGlobalNameConflicts(&conflicting_name));
13465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("a", conflicting_name);
134758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
134858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
134958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
135058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Varyings go over 8 rows.
135158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, TooManyVaryings) {
135258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexVaryings[] = {
135358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
135458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
135558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
135658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVaryings[] = {
135758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
135858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
135958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
136058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
136158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      kVertexVaryings, 2, kFragmentVaryings, 2);
136258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(
13645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
136558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, false));
136658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
136758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
136858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Varyings go over 8 rows but some are inactive
136958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, TooManyInactiveVaryings) {
137058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kVertexVaryings[] = {
137158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
137258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
137358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
137458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const VarInfo kFragmentVaryings[] = {
137558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
137658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
137758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
137858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Program* program = SetupShaderVariableTest(
137958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      kVertexVaryings, 2, kFragmentVaryings, 2);
138058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(
13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      program->CheckVaryingsPacking(Program::kCountOnlyStaticallyUsed));
138358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_TRUE(LinkAsExpected(program, true));
138458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
138558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Varyings go over 8 rows but some are inactive.
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// However, we still fail the check if kCountAll option is used.
13885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, CountAllVaryingsInPacking) {
13895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const VarInfo kVertexVaryings[] = {
13905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 1, "a", kVarVarying },
13915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
13925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
13935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const VarInfo kFragmentVaryings[] = {
13945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      { SH_FLOAT_VEC4, 4, SH_PRECISION_MEDIUMP, 0, "a", kVarVarying },
13955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      { SH_FLOAT_VEC4, 5, SH_PRECISION_MEDIUMP, 1, "b", kVarVarying }
13965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
13975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Program* program = SetupShaderVariableTest(
13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kVertexVaryings, 2, kFragmentVaryings, 2);
13995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(program->CheckVaryingsPacking(Program::kCountAll));
14015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
14025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, ClearWithSamplerTypes) {
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, NULL, NULL);
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, NULL, NULL);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1234;
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 5679;
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
14202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLenum kSamplerTypes[] = {
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GL_SAMPLER_2D,
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GL_SAMPLER_CUBE,
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GL_SAMPLER_EXTERNAL_OES,
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GL_SAMPLER_3D_OES,
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GL_SAMPLER_2D_RECT_ARB,
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumSamplerTypes = arraysize(kSamplerTypes);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t ii = 0; ii < kNumSamplerTypes; ++ii) {
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kUniform1Name,
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1Size,
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1Type,
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1FakeLocation,
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1RealLocation,
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1DesiredLocation,
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform1Name,
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      },
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kUniform2Name,
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform2Size,
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kSamplerTypes[ii],
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform2FakeLocation,
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform2RealLocation,
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform2DesiredLocation,
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform2Name,
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      },
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { kUniform3BadName,
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3Size,
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3Type,
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3FakeLocation,
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3RealLocation,
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3DesiredLocation,
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUniform3GoodName,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      },
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t kNumAttribs = arraysize(kAttribs);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t kNumUniforms = arraysize(kUniforms);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                kServiceProgramId);
14685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
14695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  base::Bind(&ShaderCacheCb));
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupExpectationsForClearingUniforms(kUniforms, kNumUniforms);
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    manager_.ClearUniforms(program);
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithShaderTest, BindUniformLocation) {
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderClientId = 2001;
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderClientId = 2002;
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kVShaderServiceId = 3001;
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLuint kFShaderServiceId = 3002;
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kUniform1DesiredLocation = 10;
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kUniform2DesiredLocation = -1;
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GLint kUniform3DesiredLocation = 5;
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vshader = shader_manager_.CreateShader(
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kVShaderClientId, kVShaderServiceId, GL_VERTEX_SHADER);
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(vshader != NULL);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vshader->SetStatus(true, NULL, NULL);
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fshader = shader_manager_.CreateShader(
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kFShaderClientId, kFShaderServiceId, GL_FRAGMENT_SHADER);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fshader != NULL);
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fshader->SetStatus(true, NULL, NULL);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1234;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 5679;
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program = manager_.CreateProgram(
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kClientProgramId, kServiceProgramId);
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(program != NULL);
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, vshader));
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->AttachShader(&shader_manager_, fshader));
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->SetUniformLocationBinding(
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Name, kUniform1DesiredLocation));
15022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(program->SetUniformLocationBinding(
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3BadName, kUniform3DesiredLocation));
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ProgramManagerWithShaderTest::AttribInfo kAttribs[] = {
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, },
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, },
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, },
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManagerWithShaderTest::UniformInfo kUniforms[] = {
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform1Name,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Size,
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Type,
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1FakeLocation,
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1RealLocation,
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1DesiredLocation,
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform1Name,
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform2Name,
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Size,
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Type,
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2FakeLocation,
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2RealLocation,
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2DesiredLocation,
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform2Name,
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kUniform3BadName,
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Size,
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3Type,
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3FakeLocation,
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3RealLocation,
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3DesiredLocation,
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUniform3GoodName,
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumAttribs = arraysize(kAttribs);
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kNumUniforms = arraysize(kUniforms);
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupShader(kAttribs, kNumAttribs, kUniforms, kNumUniforms,
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              kServiceProgramId);
15415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  program->Link(NULL, NULL, NULL, Program::kCountOnlyStaticallyUsed,
15425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                base::Bind(&ShaderCacheCb));
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform1DesiredLocation,
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform1Name));
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3DesiredLocation,
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform3BadName));
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUniform3DesiredLocation,
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            program->GetUniformFakeLocation(kUniform3GoodName));
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class ProgramManagerWithCacheTest : public GpuServiceTest {
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kClientProgramId = 1;
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kServiceProgramId = 10;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kVertexShaderClientId = 2;
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kFragmentShaderClientId = 20;
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kVertexShaderServiceId = 3;
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const GLuint kFragmentShaderServiceId = 30;
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManagerWithCacheTest()
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : cache_(new MockProgramCache()),
156358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        manager_(cache_.get(), kMaxVaryingVectors),
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vertex_shader_(NULL),
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fragment_shader_(NULL),
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program_(NULL) {
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ProgramManagerWithCacheTest() {
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    manager_.Destroy(false);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shader_manager_.Destroy(false);
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    GpuServiceTest::SetUp();
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    vertex_shader_ = shader_manager_.CreateShader(
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kVertexShaderClientId, kVertexShaderServiceId, GL_VERTEX_SHADER);
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fragment_shader_ = shader_manager_.CreateShader(
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       kFragmentShaderClientId, kFragmentShaderServiceId, GL_FRAGMENT_SHADER);
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(vertex_shader_ != NULL);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(fragment_shader_ != NULL);
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vertex_shader_->UpdateSource("lka asjf bjajsdfj");
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fragment_shader_->UpdateSource("lka asjf a   fasgag 3rdsf3 bjajsdfj");
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_ = manager_.CreateProgram(
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kClientProgramId, kServiceProgramId);
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(program_ != NULL);
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_->AttachShader(&shader_manager_, vertex_shader_);
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    program_->AttachShader(&shader_manager_, fragment_shader_);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetShadersCompiled() {
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    vertex_shader_->SetStatus(true, NULL, NULL);
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fragment_shader_->SetStatus(true, NULL, NULL);
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetProgramCached() {
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache_->LinkedProgramCacheSuccess(
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vertex_shader_->source()->c_str(),
160290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fragment_shader_->source()->c_str(),
160490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &program_->bind_attrib_location_map());
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramCached() {
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetExpectationsForProgramCached(program_,
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    vertex_shader_,
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    fragment_shader_);
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramCached(
16152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Program* program,
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* vertex_shader,
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* fragment_shader) {
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->service_id(),
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vertex_shader,
162190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fragment_shader,
162390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &program->bind_attrib_location_map(),
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        _)).Times(1);
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForNotCachingProgram() {
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetExpectationsForNotCachingProgram(program_,
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        vertex_shader_,
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        fragment_shader_);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForNotCachingProgram(
16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Program* program,
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* vertex_shader,
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* fragment_shader) {
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*cache_.get(), SaveLinkedProgram(
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        program->service_id(),
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        vertex_shader,
164190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        fragment_shader,
164390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        NULL,
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &program->bind_attrib_location_map(),
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        _)).Times(0);
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLoad(ProgramCache::ProgramLoadResult result) {
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetExpectationsForProgramLoad(kServiceProgramId,
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  program_,
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  vertex_shader_,
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  fragment_shader_,
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  result);
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLoad(
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GLuint service_program_id,
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Program* program,
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* vertex_shader,
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shader* fragment_shader,
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProgramCache::ProgramLoadResult result) {
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*cache_.get(),
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                LoadLinkedProgram(service_program_id,
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  vertex_shader,
166590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  NULL,
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  fragment_shader,
166790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  NULL,
1668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  &program->bind_attrib_location_map(),
1669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  _))
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(Return(result));
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLoadSuccess() {
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetExpectationsForProgramLoadSuccess(kServiceProgramId);
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLoadSuccess(GLuint service_program_id) {
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestHelper::SetupProgramSuccessExpectations(gl_.get(),
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                NULL,
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                0,
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                NULL,
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                0,
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                service_program_id);
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLink() {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetExpectationsForProgramLink(kServiceProgramId);
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForProgramLink(GLuint service_program_id) {
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_CALL(*gl_.get(),
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  ProgramParameteri(service_program_id,
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    PROGRAM_BINARY_RETRIEVABLE_HINT,
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    GL_TRUE)).Times(1);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetExpectationsForSuccessCompile(
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const Shader* shader) {
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GLuint shader_id = shader->service_id();
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* src = shader->source()->c_str();
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(),
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(SetArgumentPointee<2>(GL_TRUE));
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetExpectationsForNoCompile(const Shader* shader) {
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GLuint shader_id = shader->service_id();
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* src = shader->source()->c_str();
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(),
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(0);
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(0);
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Times(0);
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetExpectationsForErrorCompile(const Shader* shader) {
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GLuint shader_id = shader->service_id();
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* src = shader->source()->c_str();
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(),
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ShaderSource(shader_id, 1, Pointee(src), NULL)).Times(1);
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), CompileShader(shader_id)).Times(1);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_COMPILE_STATUS, _))
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(SetArgumentPointee<2>(GL_FALSE));
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), GetShaderiv(shader_id, GL_INFO_LOG_LENGTH, _))
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillOnce(SetArgumentPointee<2>(0));
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(*gl_.get(), GetShaderInfoLog(shader_id, 0, _, _))
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Times(1);
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<MockProgramCache> cache_;
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProgramManager manager_;
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* vertex_shader_;
17392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shader* fragment_shader_;
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Program* program_;
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ShaderManager shader_manager_;
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GCC requires these declarations, but MSVC requires they not be present
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef COMPILER_MSVC
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kClientProgramId;
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kServiceProgramId;
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kVertexShaderClientId;
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kFragmentShaderClientId;
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kVertexShaderServiceId;
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GLuint ProgramManagerWithCacheTest::kFragmentShaderServiceId;
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithCacheTest, CacheProgramOnSuccessfulLink) {
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetShadersCompiled();
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForProgramLink();
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForProgramCached();
17585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
17595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ProgramManagerWithCacheTest, LoadProgramOnProgramCacheHit) {
1763bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  SetShadersCompiled();
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetProgramCached();
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForNoCompile(vertex_shader_);
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForNoCompile(fragment_shader_);
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForProgramLoad(ProgramCache::PROGRAM_LOAD_SUCCESS);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForNotCachingProgram();
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpectationsForProgramLoadSuccess();
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(program_->Link(NULL, NULL, NULL,
17735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      Program::kCountOnlyStaticallyUsed, base::Bind(&ShaderCacheCb)));
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1778