// 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::kMaxRectangleTextureSize;
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();
  if (strstr(extensions, "GL_ARB_texture_rectangle")) {
    EXPECT_CALL(*gl, GetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE, _))
        .WillOnce(SetArgumentPointee<1>(kMaxRectangleTextureSize))
        .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 tx_ids[] = {101, 102};
    static const GLuint fb_ids[] = {103, 104};
    const GLsizei width = 16;
    EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
        .WillOnce(SetArgumentPointee<1>(fb_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
        .WillOnce(SetArgumentPointee<1>(tx_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenTextures(1, _))
        .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
        .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_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, fb_ids[1]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_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, fb_ids[0]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_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();
  }

  if (is_es3 || strstr(extensions, "GL_EXT_texture_rg") ||
      (strstr(extensions, "GL_ARB_texture_rg"))) {
    static const GLuint tx_ids[] = {101, 102};
    static const GLuint fb_ids[] = {103, 104};
    const GLsizei width = 1;
    EXPECT_CALL(*gl, GetIntegerv(GL_FRAMEBUFFER_BINDING, _))
        .WillOnce(SetArgumentPointee<1>(fb_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GetIntegerv(GL_TEXTURE_BINDING_2D, _))
        .WillOnce(SetArgumentPointee<1>(tx_ids[0]))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenTextures(1, _))
        .WillOnce(SetArrayArgument<1>(tx_ids + 1, tx_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[1]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, TexImage2D(GL_TEXTURE_2D, 0, _, width, width, 0,
        GL_RED_EXT, GL_UNSIGNED_BYTE, _))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, GenFramebuffersEXT(1, _))
        .WillOnce(SetArrayArgument<1>(fb_ids + 1, fb_ids + 2))
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindFramebufferEXT(GL_FRAMEBUFFER, fb_ids[1]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, FramebufferTexture2DEXT(GL_FRAMEBUFFER,
        GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tx_ids[1], 0))
        .Times(1)
        .RetiresOnSaturation();
    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, fb_ids[0]))
        .Times(1)
        .RetiresOnSaturation();
    EXPECT_CALL(*gl, BindTexture(GL_TEXTURE_2D, tx_ids[0]))
        .Times(1)
        .RetiresOnSaturation();
#if DCHECK_IS_ON
    EXPECT_CALL(*gl, GetError())
        .WillOnce(Return(GL_NO_ERROR))
        .RetiresOnSaturation();
#endif
  }
}

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

