// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/service/test_helper.h"

#include <algorithm>
#include <string>

#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/error_state_mock.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/mocks.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::MatcherCast;
using ::testing::Pointee;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SetArrayArgument;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;

namespace gpu {
namespace gles2 {

namespace {

template<typename T>
T ConstructShaderVariable(
    GLenum type, GLint array_size, GLenum precision,
    bool static_use, const std::string& name) {
  T var;
  var.type = type;
  var.arraySize = array_size;
  var.precision = precision;
  var.staticUse = static_use;
  var.name = name;
  var.mappedName = name;  // No name hashing.
  return var;
}

}  // namespace anonymous

// GCC requires these declarations, but MSVC requires they not be present
#ifndef COMPILER_MSVC
const GLuint TestHelper::kServiceBlackTexture2dId;
const GLuint TestHelper::kServiceDefaultTexture2dId;
const GLuint TestHelper::kServiceBlackTextureCubemapId;
const GLuint TestHelper::kServiceDefaultTextureCubemapId;
const GLuint TestHelper::kServiceBlackExternalTextureId;
const GLuint TestHelper::kServiceDefaultExternalTextureId;
const GLuint TestHelper::kServiceBlackRectangleTextureId;
const GLuint TestHelper::kServiceDefaultRectangleTextureId;

const GLint TestHelper::kMaxSamples;
const GLint TestHelper::kMaxRenderbufferSize;
const GLint TestHelper::kMaxTextureSize;
const GLint TestHelper::kMaxCubeMapTextureSize;
const GLint TestHelper::kNumVertexAttribs;
const GLint TestHelper::kNumTextureUnits;
const GLint TestHelper::kMaxTextureImageUnits;
const GLint TestHelper::kMaxVertexTextureImageUnits;
const GLint TestHelper::kMaxFragmentUniformVectors;
const GLint TestHelper::kMaxFragmentUniformComponents;
const GLint TestHelper::kMaxVaryingVectors;
const GLint TestHelper::kMaxVaryingFloats;
const GLint TestHelper::kMaxVertexUniformVectors;
const GLint TestHelper::kMaxVertexUniformComponents;
#endif

void TestHelper::SetupTextureInitializationExpectations(
    ::gfx::MockGLInterface* gl,
    GLenum target,
    bool use_default_textures) {
  InSequence sequence;

  bool needs_initialization = (target != GL_TEXTURE_EXTERNAL_OES);
  bool needs_faces = (target == GL_TEXTURE_CUBE_MAP);

  static GLuint texture_2d_ids[] = {
    kServiceBlackTexture2dId,
    kServiceDefaultTexture2dId };
  static GLuint texture_cube_map_ids[] = {
    kServiceBlackTextureCubemapId,
    kServiceDefaultTextureCubemapId };
  static GLuint texture_external_oes_ids[] = {
    kServiceBlackExternalTextureId,
    kServiceDefaultExternalTextureId };
  static GLuint texture_rectangle_arb_ids[] = {
    kServiceBlackRectangleTextureId,
    kServiceDefaultRectangleTextureId };

  const GLuint* texture_ids = NULL;
  switch (target) {
    case GL_TEXTURE_2D:
      texture_ids = &texture_2d_ids[0];
      break;
    case GL_TEXTURE_CUBE_MAP:
      texture_ids = &texture_cube_map_ids[0];
      break;
    case GL_TEXTURE_EXTERNAL_OES:
      texture_ids = &texture_external_oes_ids[0];
      break;
    case GL_TEXTURE_RECTANGLE_ARB:
      texture_ids = &texture_rectangle_arb_ids[0];
      break;
    default:
      NOTREACHED();
  }

  int array_size = use_default_textures ? 2 : 1;

  EXPECT_CALL(*gl, GenTextures(array_size, _))
      .WillOnce(SetArrayArgument<1>(texture_ids,
                                    texture_ids + array_size))
          .RetiresOnSaturation();
  for (int ii = 0; ii < array_size; ++ii) {
    EXPECT_CALL(*gl, BindTexture(target, texture_ids[ii]))
        .Times(1)
        .RetiresOnSaturation();
    if (needs_initialization) {
      if (needs_faces) {
        static GLenum faces[] = {
          GL_TEXTURE_CUBE_MAP_POSITIVE_X,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
          GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
          GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
          GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
        };
        for (size_t ii = 0; ii < arraysize(faces); ++ii) {
          EXPECT_CALL(*gl, TexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                                      GL_UNSIGNED_BYTE, _))
              .Times(1)
              .RetiresOnSaturation();
        }
      } else {
        EXPECT_CALL(*gl, TexImage2D(target, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                                    GL_UNSIGNED_BYTE, _))
            .Times(1)
            .RetiresOnSaturation();
      }
    }
  }
  EXPECT_CALL(*gl, BindTexture(target, 0))
      .Times(1)
      .RetiresOnSaturation();
}

void TestHelper::SetupTextureManagerInitExpectations(
    ::gfx::MockGLInterface* gl,
    const char* extensions,
    bool use_default_textures) {
  InSequence sequence;

  SetupTextureInitializationExpectations(
      gl, GL_TEXTURE_2D, use_default_textures);
  SetupTextureInitializationExpectations(
      gl, GL_TEXTURE_CUBE_MAP, use_default_textures);

  bool ext_image_external = false;
  bool arb_texture_rectangle = false;
  base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
  while (t.GetNext()) {
    if (t.token() == "GL_OES_EGL_image_external") {
      ext_image_external = true;
      break;
    }
    if (t.token() == "GL_ARB_texture_rectangle") {
      arb_texture_rectangle = true;
      break;
    }
  }

  if (ext_image_external) {
    SetupTextureInitializationExpectations(
        gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
  }
  if (arb_texture_rectangle) {
    SetupTextureInitializationExpectations(
        gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
  }
}

void TestHelper::SetupTextureDestructionExpectations(
    ::gfx::MockGLInterface* gl,
    GLenum target,
    bool use_default_textures) {
  if (!use_default_textures)
    return;

  GLuint texture_id = 0;
  switch (target) {
    case GL_TEXTURE_2D:
      texture_id = kServiceDefaultTexture2dId;
      break;
    case GL_TEXTURE_CUBE_MAP:
      texture_id = kServiceDefaultTextureCubemapId;
      break;
    case GL_TEXTURE_EXTERNAL_OES:
      texture_id = kServiceDefaultExternalTextureId;
      break;
    case GL_TEXTURE_RECTANGLE_ARB:
      texture_id = kServiceDefaultRectangleTextureId;
      break;
    default:
      NOTREACHED();
  }

  EXPECT_CALL(*gl, DeleteTextures(1, Pointee(texture_id)))
      .Times(1)
      .RetiresOnSaturation();
}

void TestHelper::SetupTextureManagerDestructionExpectations(
    ::gfx::MockGLInterface* gl,
    const char* extensions,
    bool use_default_textures) {
  SetupTextureDestructionExpectations(gl, GL_TEXTURE_2D, use_default_textures);
  SetupTextureDestructionExpectations(
      gl, GL_TEXTURE_CUBE_MAP, use_default_textures);

  bool ext_image_external = false;
  bool arb_texture_rectangle = false;
  base::CStringTokenizer t(extensions, extensions + strlen(extensions), " ");
  while (t.GetNext()) {
    if (t.token() == "GL_OES_EGL_image_external") {
      ext_image_external = true;
      break;
    }
    if (t.token() == "GL_ARB_texture_rectangle") {
      arb_texture_rectangle = true;
      break;
    }
  }

  if (ext_image_external) {
    SetupTextureDestructionExpectations(
        gl, GL_TEXTURE_EXTERNAL_OES, use_default_textures);
  }
  if (arb_texture_rectangle) {
    SetupTextureDestructionExpectations(
        gl, GL_TEXTURE_RECTANGLE_ARB, use_default_textures);
  }

  EXPECT_CALL(*gl, DeleteTextures(4, _))
      .Times(1)
      .RetiresOnSaturation();
}

void TestHelper::SetupContextGroupInitExpectations(
    ::gfx::MockGLInterface* gl,
    const DisallowedFeatures& disallowed_features,
    const char* extensions,
    const char* gl_version,
    bool bind_generates_resource) {
  InSequence sequence;

  SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", gl_version);

  std::string l_version(base::StringToLowerASCII(std::string(gl_version)));
  bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");

  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RENDERBUFFER_SIZE, _))
      .WillOnce(SetArgumentPointee<1>(kMaxRenderbufferSize))
      .RetiresOnSaturation();
  if (strstr(extensions, "GL_EXT_framebuffer_multisample") ||
      strstr(extensions, "GL_EXT_multisampled_render_to_texture") || is_es3) {
    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES, _))
        .WillOnce(SetArgumentPointee<1>(kMaxSamples))
        .RetiresOnSaturation();
  } else if (strstr(extensions, "GL_IMG_multisampled_render_to_texture")) {
    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_SAMPLES_IMG, _))
        .WillOnce(SetArgumentPointee<1>(kMaxSamples))
        .RetiresOnSaturation();
  }
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
      .WillOnce(SetArgumentPointee<1>(kNumVertexAttribs))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, _))
      .WillOnce(SetArgumentPointee<1>(kNumTextureUnits))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_SIZE, _))
      .WillOnce(SetArgumentPointee<1>(kMaxTextureSize))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, _))
      .WillOnce(SetArgumentPointee<1>(kMaxCubeMapTextureSize))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, _))
      .WillOnce(SetArgumentPointee<1>(kMaxTextureImageUnits))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, _))
      .WillOnce(SetArgumentPointee<1>(kMaxVertexTextureImageUnits))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, _))
      .WillOnce(SetArgumentPointee<1>(kMaxFragmentUniformComponents))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VARYING_FLOATS, _))
      .WillOnce(SetArgumentPointee<1>(kMaxVaryingFloats))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, _))
      .WillOnce(SetArgumentPointee<1>(kMaxVertexUniformComponents))
      .RetiresOnSaturation();

  bool use_default_textures = bind_generates_resource;
  SetupTextureManagerInitExpectations(gl, extensions, use_default_textures);
}

void TestHelper::SetupFeatureInfoInitExpectations(
      ::gfx::MockGLInterface* gl, const char* extensions) {
  SetupFeatureInfoInitExpectationsWithGLVersion(gl, extensions, "", "");
}

void TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
     ::gfx::MockGLInterface* gl,
     const char* extensions,
     const char* gl_renderer,
     const char* gl_version) {
  InSequence sequence;

  EXPECT_CALL(*gl, GetString(GL_EXTENSIONS))
      .WillOnce(Return(reinterpret_cast<const uint8*>(extensions)))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetString(GL_RENDERER))
      .WillOnce(Return(reinterpret_cast<const uint8*>(gl_renderer)))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl, GetString(GL_VERSION))
      .WillOnce(Return(reinterpret_cast<const uint8*>(gl_version)))
      .RetiresOnSaturation();

  std::string l_version(base::StringToLowerASCII(std::string(gl_version)));
  bool is_es3 = (l_version.substr(0, 12) == "opengl es 3.");

  if (strstr(extensions, "GL_ARB_texture_float") ||
      (is_es3 && strstr(extensions, "GL_EXT_color_buffer_float"))) {
    static const GLuint gl_ids[] = {101, 102};
    const GLsizei width = 16;
    EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
        .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
        .WillOnce(SetArgumentPointee<1>(gl_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenTextures(1, _))
        .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
        .WillOnce(SetArrayArgument<1>(gl_ids + 1, gl_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[1]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
        GL_NEAREST))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0,
        GL_RGBA, GL_FLOAT, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[1]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl_ids[1], 0))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
        .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0,
        GL_RGB, GL_FLOAT, _))
        .Times(1)
        .RetiresOnSaturation();
    if (is_es3) {
      EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
          .WillOnce(Return(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT))
          .RetiresOnSaturation();
    } else {
      EXPECT_CALL(*gl, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
          .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
          .RetiresOnSaturation();
    }
    EXPECT_CALL(*gl, DeleteFramebuffersEXT(1, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, DeleteTextures(1, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, gl_ids[0]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, gl_ids[0]))
        .Times(1)
        .RetiresOnSaturation();
#if DCHECK_IS_ON
    EXPECT_CALL(*gl, GetError())
        .WillOnce(Return(GL_NO_ERROR))
        .RetiresOnSaturation();
#endif
  }

  if (strstr(extensions, "GL_EXT_draw_buffers") ||
      strstr(extensions, "GL_ARB_draw_buffers") ||
      (is_es3 && strstr(extensions, "GL_NV_draw_buffers"))) {
    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, _))
        .WillOnce(SetArgumentPointee<1>(8))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, _))
        .WillOnce(SetArgumentPointee<1>(8))
        .RetiresOnSaturation();
  }
}

void TestHelper::SetupExpectationsForClearingUniforms(
    ::gfx::MockGLInterface* gl, UniformInfo* uniforms, size_t num_uniforms) {
  for (size_t ii = 0; ii < num_uniforms; ++ii) {
    const UniformInfo& info = uniforms[ii];
    switch (info.type) {
    case GL_FLOAT:
      EXPECT_CALL(*gl, Uniform1fv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_VEC2:
      EXPECT_CALL(*gl, Uniform2fv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_VEC3:
      EXPECT_CALL(*gl, Uniform3fv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_VEC4:
      EXPECT_CALL(*gl, Uniform4fv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_INT:
    case GL_BOOL:
    case GL_SAMPLER_2D:
    case GL_SAMPLER_CUBE:
    case GL_SAMPLER_EXTERNAL_OES:
    case GL_SAMPLER_3D_OES:
    case GL_SAMPLER_2D_RECT_ARB:
      EXPECT_CALL(*gl, Uniform1iv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_INT_VEC2:
    case GL_BOOL_VEC2:
      EXPECT_CALL(*gl, Uniform2iv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_INT_VEC3:
    case GL_BOOL_VEC3:
      EXPECT_CALL(*gl, Uniform3iv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_INT_VEC4:
    case GL_BOOL_VEC4:
      EXPECT_CALL(*gl, Uniform4iv(info.real_location, info.size, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_MAT2:
      EXPECT_CALL(*gl, UniformMatrix2fv(
          info.real_location, info.size, false, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_MAT3:
      EXPECT_CALL(*gl, UniformMatrix3fv(
          info.real_location, info.size, false, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    case GL_FLOAT_MAT4:
      EXPECT_CALL(*gl, UniformMatrix4fv(
          info.real_location, info.size, false, _))
          .Times(1)
          .RetiresOnSaturation();
      break;
    default:
      NOTREACHED();
      break;
    }
  }
}

void TestHelper::SetupProgramSuccessExpectations(
    ::gfx::MockGLInterface* gl,
    AttribInfo* attribs, size_t num_attribs,
    UniformInfo* uniforms, size_t num_uniforms,
    GLuint service_id) {
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_LINK_STATUS, _))
      .WillOnce(SetArgumentPointee<2>(1))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_INFO_LOG_LENGTH, _))
      .WillOnce(SetArgumentPointee<2>(0))
      .RetiresOnSaturation();
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTES, _))
      .WillOnce(SetArgumentPointee<2>(num_attribs))
      .RetiresOnSaturation();
  size_t max_attrib_len = 0;
  for (size_t ii = 0; ii < num_attribs; ++ii) {
    size_t len = strlen(attribs[ii].name) + 1;
    max_attrib_len = std::max(max_attrib_len, len);
  }
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, _))
      .WillOnce(SetArgumentPointee<2>(max_attrib_len))
      .RetiresOnSaturation();

  for (size_t ii = 0; ii < num_attribs; ++ii) {
    const AttribInfo& info = attribs[ii];
    EXPECT_CALL(*gl,
        GetActiveAttrib(service_id, ii,
                        max_attrib_len, _, _, _, _))
        .WillOnce(DoAll(
            SetArgumentPointee<3>(strlen(info.name)),
            SetArgumentPointee<4>(info.size),
            SetArgumentPointee<5>(info.type),
            SetArrayArgument<6>(info.name,
                                info.name + strlen(info.name) + 1)))
        .RetiresOnSaturation();
    if (!ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) {
      EXPECT_CALL(*gl, GetAttribLocation(service_id, StrEq(info.name)))
          .WillOnce(Return(info.location))
          .RetiresOnSaturation();
    }
  }
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_ACTIVE_UNIFORMS, _))
      .WillOnce(SetArgumentPointee<2>(num_uniforms))
      .RetiresOnSaturation();

  size_t max_uniform_len = 0;
  for (size_t ii = 0; ii < num_uniforms; ++ii) {
    size_t len = strlen(uniforms[ii].name) + 1;
    max_uniform_len = std::max(max_uniform_len, len);
  }
  EXPECT_CALL(*gl,
      GetProgramiv(service_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, _))
      .WillOnce(SetArgumentPointee<2>(max_uniform_len))
      .RetiresOnSaturation();
  for (size_t ii = 0; ii < num_uniforms; ++ii) {
    const UniformInfo& info = uniforms[ii];
    EXPECT_CALL(*gl,
        GetActiveUniform(service_id, ii,
                         max_uniform_len, _, _, _, _))
        .WillOnce(DoAll(
            SetArgumentPointee<3>(strlen(info.name)),
            SetArgumentPointee<4>(info.size),
            SetArgumentPointee<5>(info.type),
            SetArrayArgument<6>(info.name,
                                info.name + strlen(info.name) + 1)))
        .RetiresOnSaturation();
  }

  for (int pass = 0; pass < 2; ++pass) {
    for (size_t ii = 0; ii < num_uniforms; ++ii) {
      const UniformInfo& info = uniforms[ii];
      if (ProgramManager::IsInvalidPrefix(info.name, strlen(info.name))) {
        continue;
      }
      if (pass == 0) {
        EXPECT_CALL(*gl, GetUniformLocation(service_id, StrEq(info.name)))
            .WillOnce(Return(info.real_location))
            .RetiresOnSaturation();
      }
      if ((pass == 0 && info.desired_location >= 0) ||
          (pass == 1 && info.desired_location < 0)) {
        if (info.size > 1) {
          std::string base_name = info.name;
          size_t array_pos = base_name.rfind("[0]");
          if (base_name.size() > 3 && array_pos == base_name.size() - 3) {
            base_name = base_name.substr(0, base_name.size() - 3);
          }
          for (GLsizei jj = 1; jj < info.size; ++jj) {
            std::string element_name(
                std::string(base_name) + "[" + base::IntToString(jj) + "]");
            EXPECT_CALL(*gl, GetUniformLocation(
                service_id, StrEq(element_name)))
                .WillOnce(Return(info.real_location + jj * 2))
                .RetiresOnSaturation();
          }
        }
      }
    }
  }
}

void TestHelper::SetupShader(
    ::gfx::MockGLInterface* gl,
    AttribInfo* attribs, size_t num_attribs,
    UniformInfo* uniforms, size_t num_uniforms,
    GLuint service_id) {
  InSequence s;

  EXPECT_CALL(*gl,
      LinkProgram(service_id))
      .Times(1)
      .RetiresOnSaturation();

  SetupProgramSuccessExpectations(
      gl, attribs, num_attribs, uniforms, num_uniforms, service_id);
}

void TestHelper::DoBufferData(
    ::gfx::MockGLInterface* gl, MockErrorState* error_state,
    BufferManager* manager, Buffer* buffer, GLsizeiptr size, GLenum usage,
    const GLvoid* data, GLenum error) {
  EXPECT_CALL(*error_state, CopyRealGLErrorsToWrapper(_, _, _))
      .Times(1)
      .RetiresOnSaturation();
  if (manager->IsUsageClientSideArray(usage)) {
    EXPECT_CALL(*gl, BufferData(
        buffer->target(), 0, _, usage))
        .Times(1)
        .RetiresOnSaturation();
  } else {
    EXPECT_CALL(*gl, BufferData(
        buffer->target(), size, _, usage))
        .Times(1)
        .RetiresOnSaturation();
  }
  EXPECT_CALL(*error_state, PeekGLError(_, _, _))
      .WillOnce(Return(error))
      .RetiresOnSaturation();
  manager->DoBufferData(error_state, buffer, size, usage, data);
}

void TestHelper::SetTexParameteriWithExpectations(
    ::gfx::MockGLInterface* gl, MockErrorState* error_state,
    TextureManager* manager, TextureRef* texture_ref,
    GLenum pname, GLint value, GLenum error) {
  if (error == GL_NO_ERROR) {
    if (pname != GL_TEXTURE_POOL_CHROMIUM) {
      EXPECT_CALL(*gl, TexParameteri(texture_ref->texture()->target(),
                                     pname, value))
          .Times(1)
          .RetiresOnSaturation();
    }
  } else if (error == GL_INVALID_ENUM) {
    EXPECT_CALL(*error_state, SetGLErrorInvalidEnum(_, _, _, value, _))
        .Times(1)
        .RetiresOnSaturation();
  } else {
    EXPECT_CALL(*error_state, SetGLErrorInvalidParami(_, _, error, _, _, _))
        .Times(1)
        .RetiresOnSaturation();
  }
  manager->SetParameteri("", error_state, texture_ref, pname, value);
}

// static
void TestHelper::SetShaderStates(
      ::gfx::MockGLInterface* gl, Shader* shader,
      bool expected_valid,
      const std::string* const expected_log_info,
      const std::string* const expected_translated_source,
      const AttributeMap* const expected_attrib_map,
      const UniformMap* const expected_uniform_map,
      const VaryingMap* const expected_varying_map,
      const NameMap* const expected_name_map) {
  const std::string empty_log_info;
  const std::string* log_info = (expected_log_info && !expected_valid) ?
      expected_log_info : &empty_log_info;
  const std::string empty_translated_source;
  const std::string* translated_source =
      (expected_translated_source && expected_valid) ?
          expected_translated_source : &empty_translated_source;
  const AttributeMap empty_attrib_map;
  const AttributeMap* attrib_map = (expected_attrib_map && expected_valid) ?
      expected_attrib_map : &empty_attrib_map;
  const UniformMap empty_uniform_map;
  const UniformMap* uniform_map = (expected_uniform_map && expected_valid) ?
      expected_uniform_map : &empty_uniform_map;
  const VaryingMap empty_varying_map;
  const VaryingMap* varying_map = (expected_varying_map && expected_valid) ?
      expected_varying_map : &empty_varying_map;
  const NameMap empty_name_map;
  const NameMap* name_map = (expected_name_map && expected_valid) ?
      expected_name_map : &empty_name_map;

  MockShaderTranslator translator;
  EXPECT_CALL(translator, Translate(_,
                                    NotNull(),  // log_info
                                    NotNull(),  // translated_source
                                    NotNull(),  // attrib_map
                                    NotNull(),  // uniform_map
                                    NotNull(),  // varying_map
                                    NotNull()))  // name_map
      .WillOnce(DoAll(SetArgumentPointee<1>(*log_info),
                      SetArgumentPointee<2>(*translated_source),
                      SetArgumentPointee<3>(*attrib_map),
                      SetArgumentPointee<4>(*uniform_map),
                      SetArgumentPointee<5>(*varying_map),
                      SetArgumentPointee<6>(*name_map),
                      Return(expected_valid)))
      .RetiresOnSaturation();
  if (expected_valid) {
    EXPECT_CALL(*gl, ShaderSource(shader->service_id(), 1, _, NULL))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, CompileShader(shader->service_id()))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetShaderiv(shader->service_id(),
                                 GL_COMPILE_STATUS,
                                 NotNull()))  // status
        .WillOnce(SetArgumentPointee<2>(GL_TRUE))
        .RetiresOnSaturation();
  }
  shader->DoCompile(&translator, Shader::kGL);
}

// static
void TestHelper::SetShaderStates(
      ::gfx::MockGLInterface* gl, Shader* shader, bool valid) {
  SetShaderStates(gl, shader, valid, NULL, NULL, NULL, NULL, NULL, NULL);
}

// static
sh::Attribute TestHelper::ConstructAttribute(
    GLenum type, GLint array_size, GLenum precision,
    bool static_use, const std::string& name) {
  return ConstructShaderVariable<sh::Attribute>(
      type, array_size, precision, static_use, name);
}

// static
sh::Uniform TestHelper::ConstructUniform(
    GLenum type, GLint array_size, GLenum precision,
    bool static_use, const std::string& name) {
  return ConstructShaderVariable<sh::Uniform>(
      type, array_size, precision, static_use, name);
}

// static
sh::Varying TestHelper::ConstructVarying(
    GLenum type, GLint array_size, GLenum precision,
    bool static_use, const std::string& name) {
  return ConstructShaderVariable<sh::Varying>(
      type, array_size, precision, static_use, name);
}

ScopedGLImplementationSetter::ScopedGLImplementationSetter(
    gfx::GLImplementation implementation)
    : old_implementation_(gfx::GetGLImplementation()) {
  gfx::SetGLImplementation(implementation);
}

ScopedGLImplementationSetter::~ScopedGLImplementationSetter() {
  gfx::SetGLImplementation(old_implementation_);
}

}  // namespace gles2
}  // namespace gpu

