| Index: gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
 | 
| diff --git a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
 | 
| index a256fff89ef563a2bf3c393d475b94187e2aeaa4..5caad26e637b560e5abba16749bcf75604cf1f89 100644
 | 
| --- a/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
 | 
| +++ b/gpu/command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc
 | 
| @@ -10,8 +10,11 @@
 | 
|  #include <GLES2/gl2ext.h>
 | 
|  #include <GLES2/gl2extchromium.h>
 | 
|  
 | 
| +#include "base/command_line.h"
 | 
| +#include "base/strings/string_number_conversions.h"
 | 
|  #include "gpu/command_buffer/tests/gl_manager.h"
 | 
|  #include "gpu/command_buffer/tests/gl_test_utils.h"
 | 
| +#include "gpu/config/gpu_switches.h"
 | 
|  #include "testing/gmock/include/gmock/gmock.h"
 | 
|  #include "testing/gtest/include/gtest/gtest.h"
 | 
|  
 | 
| @@ -23,30 +26,56 @@ const CopyType kCopyTypes[] = {
 | 
|      TexImage,
 | 
|      TexSubImage,
 | 
|  };
 | 
| -}
 | 
| +
 | 
| +const GLenum kDestinationFaces[] = {
 | 
| +    GL_TEXTURE_2D,
 | 
| +    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
 | 
| +#if !defined(OS_ANDROID)
 | 
| +    // linux_android_rel_ng crashs on glReadPixels()
 | 
| +    // TODO(dshwang): exclude them for only Nvidia. crbug.com/527126
 | 
| +    // TODO(dshwang): handle Nvidia. crbug.com/528145
 | 
| +    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,
 | 
| +#endif
 | 
| +};
 | 
| +}  // namespace
 | 
|  
 | 
|  // A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
 | 
|  class GLCopyTextureCHROMIUMTest
 | 
| -    : public testing::Test,
 | 
| -      public ::testing::WithParamInterface<CopyType> {
 | 
| +    : public testing::TestWithParam<::testing::tuple<CopyType, GLenum>> {
 | 
|   protected:
 | 
|    void SetUp() override {
 | 
| -    gl_.Initialize(GLManager::Options());
 | 
| -
 | 
| +    base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
 | 
| +    // ANGLE and Nvidia fails without this workaround. crbug.com/518889
 | 
| +    command_line.AppendSwitchASCII(switches::kGpuDriverBugWorkarounds,
 | 
| +                                   base::IntToString(gpu::FORCE_CUBE_COMPLETE));
 | 
| +    gl_.InitializeWithCommandLine(GLManager::Options(), &command_line);
 | 
| +    DCHECK(gl_.workarounds().force_cube_complete);
 | 
| +
 | 
| +    // textures_[0] is source texture and textures_[1] is destination texture.
 | 
|      glGenTextures(2, textures_);
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +
 | 
| +    GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +    GLenum binding_target =
 | 
| +        gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
| +
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
|  
 | 
|      // Some drivers (NVidia/SGX) require texture settings to be a certain way or
 | 
|      // they won't report FRAMEBUFFER_COMPLETE.
 | 
| -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
| -    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| -    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
| -    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
| +    glTexParameterf(binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
| +    glTexParameterf(binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| +    glTexParameteri(binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
| +    glTexParameteri(binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
|  
 | 
|      glGenFramebuffers(1, &framebuffer_id_);
 | 
|      glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_);
 | 
| -    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
 | 
| +    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
 | 
|                             textures_[1], 0);
 | 
| +    EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
 | 
|    }
 | 
|  
 | 
|    void TearDown() override {
 | 
| @@ -55,18 +84,45 @@ class GLCopyTextureCHROMIUMTest
 | 
|      gl_.Destroy();
 | 
|    }
 | 
|  
 | 
| +  // Some drivers(Nvidia) require cube complete to do glReadPixels from the FBO.
 | 
| +  // TODO(dshwang): handle Nvidia. crbug.com/528145
 | 
| +  void MakeCubeComplete(GLenum target,
 | 
| +                        GLint internalformat,
 | 
| +                        GLenum type,
 | 
| +                        GLsizei width,
 | 
| +                        GLsizei height) {
 | 
| +    // Make the textures cube complete to bind it to FBO
 | 
| +    GLenum binding_target =
 | 
| +        gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(target);
 | 
| +    if (binding_target == GL_TEXTURE_CUBE_MAP) {
 | 
| +      glBindTexture(binding_target, textures_[1]);
 | 
| +      for (unsigned i = 0; i < 6; i++) {
 | 
| +        if (target == GL_TEXTURE_CUBE_MAP_POSITIVE_X + i)
 | 
| +          continue;
 | 
| +        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalformat,
 | 
| +                     width, height, 0, internalformat, type, nullptr);
 | 
| +        EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
 | 
| +      }
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|    GLManager gl_;
 | 
|    GLuint textures_[2];
 | 
|    GLuint framebuffer_id_;
 | 
|  };
 | 
|  
 | 
| -INSTANTIATE_TEST_CASE_P(CopyType,
 | 
| -                        GLCopyTextureCHROMIUMTest,
 | 
| -                        ::testing::ValuesIn(kCopyTypes));
 | 
| +INSTANTIATE_TEST_CASE_P(
 | 
| +    GLCopyTextureCHROMIUMTests,
 | 
| +    GLCopyTextureCHROMIUMTest,
 | 
| +    ::testing::Combine(::testing::ValuesIn(kCopyTypes),
 | 
| +                       ::testing::ValuesIn(kDestinationFaces)));
 | 
|  
 | 
|  // Test to ensure that the basic functionality of the extension works.
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, Basic) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
 | 
|  
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| @@ -74,18 +130,20 @@ TEST_P(GLCopyTextureCHROMIUMTest, Basic) {
 | 
|                 pixels);
 | 
|  
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|    } else {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                   nullptr);
 | 
|  
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, 1, 1, false, false, false);
 | 
|    }
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
 | 
| +
 | 
|    // Check the FB is still bound.
 | 
|    GLint value = 0;
 | 
|    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
 | 
| @@ -105,7 +163,11 @@ TEST_P(GLCopyTextureCHROMIUMTest, ImmutableTexture) {
 | 
|      LOG(INFO) << "GL_EXT_texture_storage not supported. Skipping test...";
 | 
|      return;
 | 
|    }
 | 
| -  CopyType copy_type = GetParam();
 | 
| +
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|  
 | 
|    uint8 pixels[1 * 4] = {255u, 0u, 0u, 255u};
 | 
|  
 | 
| @@ -114,21 +176,33 @@ TEST_P(GLCopyTextureCHROMIUMTest, ImmutableTexture) {
 | 
|    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                    pixels);
 | 
|  
 | 
| -  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -  glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
 | 
| -  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
 | 
| +  glBindTexture(binding_target, textures_[1]);
 | 
| +  glTexStorage2DEXT(binding_target, 1, GL_RGBA8_OES, 1, 1);
 | 
| +  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, dest_target,
 | 
|                           textures_[1], 0);
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|      EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
 | 
|    } else {
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, 1, 1, false, false, false);
 | 
|      EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
| +    // Similar quirk to MakeCubeComplete() for immutable texture.
 | 
| +    if (binding_target == GL_TEXTURE_CUBE_MAP) {
 | 
| +      for (unsigned i = 0; i < 6; i++) {
 | 
| +        if (dest_target == GL_TEXTURE_CUBE_MAP_POSITIVE_X + i)
 | 
| +          continue;
 | 
| +        glCopySubTextureCHROMIUM(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
 | 
| +                                 textures_[0], textures_[1], 0, 0, 0, 0, 1, 1,
 | 
| +                                 false, false, false);
 | 
| +      }
 | 
| +    }
 | 
| +    EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
 | 
| +
 | 
|      // Check the FB is still bound.
 | 
|      GLint value = 0;
 | 
|      glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
 | 
| @@ -145,7 +219,11 @@ TEST_P(GLCopyTextureCHROMIUMTest, ImmutableTexture) {
 | 
|  }
 | 
|  
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, InternalFormat) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
| +
 | 
|    GLint src_formats[] = {GL_ALPHA,     GL_RGB,             GL_RGBA,
 | 
|                           GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGRA_EXT};
 | 
|    GLint dest_formats[] = {GL_RGB, GL_RGBA};
 | 
| @@ -159,27 +237,29 @@ TEST_P(GLCopyTextureCHROMIUMTest, InternalFormat) {
 | 
|        EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
|        if (copy_type == TexImage) {
 | 
| -        glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| -                              dest_formats[dest_index], GL_UNSIGNED_BYTE,
 | 
| -                              false, false, false);
 | 
| +        glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1],
 | 
| +                              dest_formats[dest_index], GL_UNSIGNED_BYTE, false,
 | 
| +                              false, false);
 | 
|        } else {
 | 
| -        glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -        glTexImage2D(GL_TEXTURE_2D, 0, dest_formats[dest_index], 1, 1, 0,
 | 
| +        glBindTexture(binding_target, textures_[1]);
 | 
| +        glTexImage2D(dest_target, 0, dest_formats[dest_index], 1, 1, 0,
 | 
|                       dest_formats[dest_index], GL_UNSIGNED_BYTE, nullptr);
 | 
|          EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
| -        glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0,
 | 
| -                                 0, 0, 0, 1, 1, false, false, false);
 | 
| +        glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0,
 | 
| +                                 0, 0, 1, 1, false, false, false);
 | 
|        }
 | 
| -
 | 
| -      EXPECT_TRUE(GL_NO_ERROR == glGetError()) << "src_index:" << src_index
 | 
| -                                               << " dest_index:" << dest_index;
 | 
| +      EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError())
 | 
| +          << "src_index:" << src_index << " dest_index:" << dest_index;
 | 
|      }
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                 nullptr);
 | 
| @@ -191,16 +271,16 @@ TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
|    for (size_t dest_index = 0; dest_index < arraysize(unsupported_dest_formats);
 | 
|         dest_index++) {
 | 
|      if (copy_type == TexImage) {
 | 
| -      glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +      glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1],
 | 
|                              unsupported_dest_formats[dest_index],
 | 
|                              GL_UNSIGNED_BYTE, false, false, false);
 | 
|      } else {
 | 
| -      glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -      glTexImage2D(GL_TEXTURE_2D, 0, unsupported_dest_formats[dest_index], 1, 1,
 | 
| +      glBindTexture(binding_target, textures_[1]);
 | 
| +      glTexImage2D(dest_target, 0, unsupported_dest_formats[dest_index], 1, 1,
 | 
|                     0, unsupported_dest_formats[dest_index], GL_UNSIGNED_BYTE,
 | 
|                     nullptr);
 | 
| -      glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0,
 | 
| -                               0, 0, 1, 1, false, false, false);
 | 
| +      glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
| +                               0, 1, 1, false, false, false);
 | 
|      }
 | 
|      EXPECT_TRUE(GL_INVALID_OPERATION == glGetError())
 | 
|          << "dest_index:" << dest_index;
 | 
| @@ -209,7 +289,10 @@ TEST_P(GLCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
|  
 | 
|  // Test to ensure that the destination texture is redefined if the properties
 | 
|  // are different.
 | 
| -TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
 | 
| +TEST_P(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    uint8 pixels[4 * 4] = {255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u,
 | 
|                           255u, 0u, 0u, 255u, 255u, 0u, 0u, 255u};
 | 
|  
 | 
| @@ -217,40 +300,35 @@ TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
 | 
|    glTexImage2D(
 | 
|        GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 | 
|  
 | 
| -  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -  glTexImage2D(GL_TEXTURE_2D,
 | 
| -               0,
 | 
| -               GL_BGRA_EXT,
 | 
| -               1,
 | 
| -               1,
 | 
| -               0,
 | 
| -               GL_BGRA_EXT,
 | 
| -               GL_UNSIGNED_BYTE,
 | 
| -               pixels);
 | 
| +  glBindTexture(binding_target, textures_[1]);
 | 
| +  glTexImage2D(dest_target, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT,
 | 
| +               GL_UNSIGNED_BYTE, pixels);
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
|    // GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
 | 
| -  glTexSubImage2D(
 | 
| -      GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 | 
| +  glTexSubImage2D(dest_target, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +                  pixels);
 | 
|    EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
 | 
|    // GL_INVALID_VALUE due to bad dimensions.
 | 
| -  glTexSubImage2D(
 | 
| -      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
 | 
| +  glTexSubImage2D(dest_target, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
 | 
| +                  pixels);
 | 
|    EXPECT_TRUE(GL_INVALID_VALUE == glGetError());
 | 
|  
 | 
|    // If the dest texture has different properties, glCopyTextureCHROMIUM()
 | 
|    // redefines them.
 | 
| -  glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +  glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                          GL_UNSIGNED_BYTE, false, false, false);
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
|    // glTexSubImage2D() succeeds because textures_[1] is redefined into 2x2
 | 
|    // dimension and GL_RGBA format.
 | 
| -  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -  glTexSubImage2D(
 | 
| -      GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 | 
| +  glBindTexture(binding_target, textures_[1]);
 | 
| +  glTexSubImage2D(dest_target, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +                  pixels);
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
 | 
| +
 | 
|    // Check the FB is still bound.
 | 
|    GLint value = 0;
 | 
|    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
 | 
| @@ -261,7 +339,16 @@ TEST_F(GLCopyTextureCHROMIUMTest, RedefineDestinationTexture) {
 | 
|    EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
 | 
|              glCheckFramebufferStatus(GL_FRAMEBUFFER));
 | 
|  
 | 
| +#if defined(OS_MACOSX) || defined(OS_WIN)
 | 
| +  // Despite of "MakeCubeComplete()" quirk, glReadPixels still fails on
 | 
| +  // mac_chromium_rel_ng and win_chromium_rel_ng.
 | 
| +  // TODO(dshwang): exclude it for only Nvidia. crbug.com/527126
 | 
| +  GLsizei size = 2 * 2 * 4;
 | 
| +  scoped_ptr<uint8[]> read_pixels(new uint8[size]);
 | 
| +  glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, read_pixels.get());
 | 
| +#else
 | 
|    GLTestHelper::CheckPixels(1, 1, 1, 1, 0, &pixels[12]);
 | 
| +#endif
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  }
 | 
|  
 | 
| @@ -279,7 +366,10 @@ void glEnableDisable(GLint param, GLboolean value) {
 | 
|  // Validate that some basic GL state is not touched upon execution of
 | 
|  // the extension.
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
 | 
|  
 | 
|    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 | 
| @@ -289,8 +379,8 @@ TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|                 pixels);
 | 
|  
 | 
|    if (copy_type == TexSubImage) {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                   nullptr);
 | 
|    }
 | 
|  
 | 
| @@ -308,11 +398,11 @@ TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|      glActiveTexture(GL_TEXTURE1 + x);
 | 
|  
 | 
|      if (copy_type == TexImage) {
 | 
| -      glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +      glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                              GL_UNSIGNED_BYTE, false, false, false);
 | 
|      } else {
 | 
| -      glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0,
 | 
| -                               0, 0, 1, 1, false, false, false);
 | 
| +      glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
| +                               0, 1, 1, false, false, false);
 | 
|      }
 | 
|      EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
| @@ -344,7 +434,13 @@ TEST_P(GLCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|  // Verify that invocation of the extension does not modify the bound
 | 
|  // texture state.
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
| +  GLenum get_binding_target = binding_target == GL_TEXTURE_2D
 | 
| +                                  ? GL_TEXTURE_BINDING_2D
 | 
| +                                  : GL_TEXTURE_BINDING_CUBE_MAP;
 | 
|    // Setup the texture used for the extension invocation.
 | 
|    uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| @@ -352,8 +448,8 @@ TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|                 pixels);
 | 
|  
 | 
|    if (copy_type == TexSubImage) {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                   nullptr);
 | 
|    }
 | 
|  
 | 
| @@ -364,13 +460,13 @@ TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    glBindTexture(GL_TEXTURE_2D, texture_ids[0]);
 | 
|  
 | 
|    glActiveTexture(GL_TEXTURE1);
 | 
| -  glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
 | 
| +  glBindTexture(binding_target, texture_ids[1]);
 | 
|  
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|    } else {
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, 1, 1, false, false, false);
 | 
|    }
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
| @@ -380,9 +476,9 @@ TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    EXPECT_EQ(GL_TEXTURE1, active_texture);
 | 
|  
 | 
|    GLint bound_texture = 0;
 | 
| -  glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
 | 
| +  glGetIntegerv(get_binding_target, &bound_texture);
 | 
|    EXPECT_EQ(texture_ids[1], static_cast<GLuint>(bound_texture));
 | 
| -  glBindTexture(GL_TEXTURE_2D, 0);
 | 
| +  glBindTexture(binding_target, 0);
 | 
|  
 | 
|    bound_texture = 0;
 | 
|    glActiveTexture(GL_TEXTURE0);
 | 
| @@ -398,7 +494,10 @@ TEST_P(GLCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|  // Verify that invocation of the extension does not perturb the currently
 | 
|  // bound FBO state.
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    // Setup the texture used for the extension invocation.
 | 
|    uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u };
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| @@ -406,8 +505,8 @@ TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
 | 
|                 pixels);
 | 
|  
 | 
|    if (copy_type == TexSubImage) {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                   nullptr);
 | 
|    }
 | 
|  
 | 
| @@ -439,14 +538,16 @@ TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
 | 
|    GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color);
 | 
|  
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|    } else {
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, 1, 1, false, false, false);
 | 
|    }
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
 | 
| +
 | 
|    EXPECT_TRUE(glIsFramebuffer(framebuffer_id));
 | 
|  
 | 
|    // Ensure that reading from the framebuffer produces correct pixels.
 | 
| @@ -493,7 +594,10 @@ TEST_P(GLCopyTextureCHROMIUMTest, FBOStatePreserved) {
 | 
|  }
 | 
|  
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    // unbind the one created in setup.
 | 
|    glBindFramebuffer(GL_FRAMEBUFFER, 0);
 | 
|    glBindTexture(GL_TEXTURE_2D, 0);
 | 
| @@ -548,16 +652,18 @@ TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
 | 
|    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                 pixels);
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|    } else {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                   nullptr);
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, 1, 1, false, false, false);
 | 
|    }
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, 1, 1);
 | 
| +
 | 
|    // test using program after
 | 
|    glClear(GL_COLOR_BUFFER_BIT);
 | 
|    EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, zero));
 | 
| @@ -573,24 +679,29 @@ TEST_P(GLCopyTextureCHROMIUMTest, ProgramStatePreservation) {
 | 
|  
 | 
|  // Test that glCopyTextureCHROMIUM doesn't leak uninitialized textures.
 | 
|  TEST_P(GLCopyTextureCHROMIUMTest, UninitializedSource) {
 | 
| -  CopyType copy_type = GetParam();
 | 
| +  CopyType copy_type = ::testing::get<0>(GetParam());
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    const GLsizei kWidth = 64, kHeight = 64;
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
 | 
|                 GL_UNSIGNED_BYTE, nullptr);
 | 
|  
 | 
|    if (copy_type == TexImage) {
 | 
| -    glCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], GL_RGBA,
 | 
| +    glCopyTextureCHROMIUM(dest_target, textures_[0], textures_[1], GL_RGBA,
 | 
|                            GL_UNSIGNED_BYTE, false, false, false);
 | 
|    } else {
 | 
| -    glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
 | 
| +    glBindTexture(binding_target, textures_[1]);
 | 
| +    glTexImage2D(dest_target, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA,
 | 
|                   GL_UNSIGNED_BYTE, nullptr);
 | 
| -    glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 0,
 | 
| +    glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 0,
 | 
|                               0, kWidth, kHeight, false, false, false);
 | 
|    }
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, kWidth, kHeight);
 | 
| +
 | 
|    uint8 pixels[kHeight][kWidth][4] = {{{1}}};
 | 
|    glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
 | 
|    for (int x = 0; x < kWidth; ++x) {
 | 
| @@ -605,41 +716,47 @@ TEST_P(GLCopyTextureCHROMIUMTest, UninitializedSource) {
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  }
 | 
|  
 | 
| -TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureDimension) {
 | 
| +TEST_P(GLCopyTextureCHROMIUMTest, CopySubTextureDimension) {
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                 nullptr);
 | 
|  
 | 
| -  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +  glBindTexture(binding_target, textures_[1]);
 | 
| +  glTexImage2D(dest_target, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                 nullptr);
 | 
|  
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 1, 0,
 | 
| -                           0, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 1, 1, 0, 0,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
|    // xoffset < 0
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], -1, 1, 0,
 | 
| -                           0, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], -1, 1, 0, 0,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
|  
 | 
|    // x < 0
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 1, -1,
 | 
| -                           0, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 1, 1, -1, 0,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
|  
 | 
|    // xoffset + width > dest_width
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 2, 2, 0,
 | 
| -                           0, 2, 2, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 2, 2, 0, 0,
 | 
| +                           2, 2, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
|  
 | 
|    // x + width > source_width
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 0, 1,
 | 
| -                           1, 2, 2, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 0, 1, 1,
 | 
| +                           2, 2, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
|  }
 | 
|  
 | 
| -TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) {
 | 
| +TEST_P(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) {
 | 
| +  GLenum dest_target = ::testing::get<1>(GetParam());
 | 
| +  GLenum binding_target =
 | 
| +      gpu::gles2::GLES2Util::GLTextureTargetToBindingTarget(dest_target);
 | 
|    uint8 rgba_pixels[4 * 4] = {255u,
 | 
|                                0u,
 | 
|                                0u,
 | 
| @@ -662,20 +779,22 @@ TEST_F(GLCopyTextureCHROMIUMTest, CopySubTextureOffset) {
 | 
|  
 | 
|    uint8 transparent_pixels[4 * 4] = {
 | 
|        0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u};
 | 
| -  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| -  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +  glBindTexture(binding_target, textures_[1]);
 | 
| +  glTexImage2D(dest_target, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
|                 transparent_pixels);
 | 
|  
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 1, 0,
 | 
| -                           0, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 1, 1, 0, 0,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 1, 0, 1,
 | 
| -                           0, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 1, 0, 1, 0,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| -  glCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1], 0, 1, 0,
 | 
| -                           1, 1, 1, false, false, false);
 | 
| +  glCopySubTextureCHROMIUM(dest_target, textures_[0], textures_[1], 0, 1, 0, 1,
 | 
| +                           1, 1, false, false, false);
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
| +  MakeCubeComplete(dest_target, GL_RGBA, GL_UNSIGNED_BYTE, 2, 2);
 | 
| +
 | 
|    // Check the FB is still bound.
 | 
|    GLint value = 0;
 | 
|    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &value);
 | 
| 
 |