| Index: gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
 | 
| diff --git a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
 | 
| index 86b07cd024c4b54f37b54e83ecdd06a763ebb14a..d50189daff6622080cdee027f8c33f03435ad843 100644
 | 
| --- a/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
 | 
| +++ b/gpu/command_buffer/tests/gl_compressed_copy_texture_CHROMIUM_unittest.cc
 | 
| @@ -22,6 +22,12 @@ namespace gpu {
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| +enum CopyType { TexImage, TexSubImage };
 | 
| +const CopyType kCopyTypes[] = {
 | 
| +    TexImage,
 | 
| +    TexSubImage,
 | 
| +};
 | 
| +
 | 
|  const uint8 kCompressedImageColor[4] = { 255u, 0u, 0u, 255u };
 | 
|  
 | 
|  // Single compressed ATC block of source pixels all set to:
 | 
| @@ -40,6 +46,15 @@ const uint8 kCompressedImageATCIA[16] = {
 | 
|  const uint8 kCompressedImageDXT1[8] = {
 | 
|      0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa };
 | 
|  
 | 
| +// Four compressed DXT1 blocks solidly colored in red, green, blue and black:
 | 
| +// [R][G]
 | 
| +// [B][b]
 | 
| +const uint8 kCompressedImageDXT1RGB[32] = {
 | 
| +    0x0, 0xf8, 0x0, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa,
 | 
| +    0xe0, 0x7, 0xe0, 0x7, 0xaa, 0xaa, 0xaa, 0xaa,
 | 
| +    0x1f, 0x0, 0x1f, 0x0, 0xaa, 0xaa, 0xaa, 0xaa,
 | 
| +    0x0, 0x0, 0x0, 0x0, 0xaa, 0xaa, 0xaa, 0xaa };
 | 
| +
 | 
|  // Single compressed DXT5 block of source pixels all set to:
 | 
|  // kCompressedImageColor.
 | 
|  const uint8 kCompressedImageDXT5[16] = {
 | 
| @@ -51,6 +66,17 @@ const uint8 kCompressedImageDXT5[16] = {
 | 
|  const uint8 kCompressedImageETC1[8] = {
 | 
|      0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0 };
 | 
|  
 | 
| +// Single block of zeroes, used for texture pre-allocation.
 | 
| +const uint8 kInvalidCompressedImage[8] = {
 | 
| +    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
 | 
| +
 | 
| +// Four blocks of zeroes, used for texture pre-allocation.
 | 
| +const uint8 kInvalidCompressedImageLarge[32] = {
 | 
| +    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 | 
| +    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 | 
| +    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 | 
| +    0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
 | 
| +
 | 
|  void glEnableDisable(GLint param, GLboolean value) {
 | 
|    if (value)
 | 
|      glEnable(param);
 | 
| @@ -62,7 +88,8 @@ void glEnableDisable(GLint param, GLboolean value) {
 | 
|  
 | 
|  // A collection of tests that exercise the GL_CHROMIUM_copy_texture extension.
 | 
|  class GLCompressedCopyTextureCHROMIUMTest
 | 
| -    : public testing::Test {
 | 
| +    : public testing::Test,
 | 
| +      public ::testing::WithParamInterface<CopyType> {
 | 
|   protected:
 | 
|    void SetUp() override {
 | 
|      gl_.Initialize(GLManager::Options());
 | 
| @@ -100,14 +127,20 @@ class GLCompressedCopyTextureCHROMIUMTest
 | 
|    GLuint framebuffer_id_;
 | 
|  };
 | 
|  
 | 
| +INSTANTIATE_TEST_CASE_P(CopyType,
 | 
| +                        GLCompressedCopyTextureCHROMIUMTest,
 | 
| +                        ::testing::ValuesIn(kCopyTypes));
 | 
| +
 | 
|  // Test to ensure that the basic functionality of the extension works.
 | 
| -TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
 | 
| +TEST_P(GLCompressedCopyTextureCHROMIUMTest, Basic) {
 | 
|    if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
|      LOG(INFO) <<
 | 
|          "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  CopyType copy_type = GetParam();
 | 
| +
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| @@ -123,7 +156,17 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
 | 
|    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);
 | 
| -  glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  if (copy_type == TexImage) {
 | 
| +    glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  } else {
 | 
| +    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                           4, 4, 0,
 | 
| +                           sizeof(kInvalidCompressedImage),
 | 
| +                           kInvalidCompressedImage);
 | 
| +
 | 
| +    glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                       textures_[1], 0, 0, 0, 0, 4, 4);
 | 
| +  }
 | 
|    EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
|    // Load shader program.
 | 
| @@ -152,7 +195,9 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, Basic) {
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  }
 | 
|  
 | 
| -TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
 | 
| +TEST_P(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
 | 
| +  CopyType copy_type = GetParam();
 | 
| +
 | 
|    struct Image {
 | 
|      const GLint format;
 | 
|      const uint8* data;
 | 
| @@ -163,8 +208,9 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
 | 
|    };
 | 
|    ScopedVector<Image> supported_formats;
 | 
|  
 | 
| -  if (GLTestHelper::HasExtension("GL_AMD_compressed_ATC_texture") ||
 | 
| -      GLTestHelper::HasExtension("GL_ATI_texture_compression_atitc")) {
 | 
| +  if ((GLTestHelper::HasExtension("GL_AMD_compressed_ATC_texture") ||
 | 
| +      GLTestHelper::HasExtension("GL_ATI_texture_compression_atitc")) &&
 | 
| +      copy_type != TexSubImage) {
 | 
|      supported_formats.push_back(new Image(
 | 
|          GL_ATC_RGB_AMD,
 | 
|          kCompressedImageATC,
 | 
| @@ -187,7 +233,8 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
 | 
|          kCompressedImageDXT5,
 | 
|          sizeof(kCompressedImageDXT5)));
 | 
|    }
 | 
| -  if (GLTestHelper::HasExtension("GL_OES_compressed_ETC1_RGB8_texture")) {
 | 
| +  if (GLTestHelper::HasExtension("GL_OES_compressed_ETC1_RGB8_texture") &&
 | 
| +      copy_type != TexSubImage) {
 | 
|      supported_formats.push_back(new Image(
 | 
|          GL_ETC1_RGB8_OES,
 | 
|          kCompressedImageETC1,
 | 
| @@ -209,18 +256,30 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormat) {
 | 
|      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);
 | 
| -    glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +    if (copy_type == TexImage) {
 | 
| +      glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                      textures_[1]);
 | 
| +    } else {
 | 
| +      glCompressedTexImage2D(GL_TEXTURE_2D, 0, image->format, 4, 4, 0,
 | 
| +                             sizeof(kInvalidCompressedImage),
 | 
| +                             kInvalidCompressedImage);
 | 
| +
 | 
| +      glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                         textures_[1], 0, 0, 0, 0, 4, 4);
 | 
| +    }
 | 
|      EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
| +TEST_P(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
|    if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
|      LOG(INFO) <<
 | 
|          "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  CopyType copy_type = GetParam();
 | 
| +
 | 
|    const uint8 kUncompressedPixels[1 * 4] = { 255u, 0u, 0u, 255u };
 | 
|  
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| @@ -239,19 +298,29 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, InternalFormatNotSupported) {
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
|  
 | 
|    // Check that the GL_RGBA format reports an error.
 | 
| -  glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  if (copy_type == TexImage) {
 | 
| +    glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  } else {
 | 
| +    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
 | 
| +                 kUncompressedPixels);
 | 
| +
 | 
| +    glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                       textures_[1], 0, 0, 0, 0, 1, 1);
 | 
| +  }
 | 
|    EXPECT_TRUE(GL_INVALID_OPERATION == glGetError());
 | 
|  }
 | 
|  
 | 
|  // Validate that some basic GL state is not touched upon execution of
 | 
|  // the extension.
 | 
| -TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
| +TEST_P(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|    if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
|      LOG(INFO) <<
 | 
|          "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  CopyType copy_type = GetParam();
 | 
| +
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| @@ -268,6 +337,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
|  
 | 
| +  if (copy_type == TexSubImage) {
 | 
| +    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                           4, 4, 0,
 | 
| +                           sizeof(kInvalidCompressedImage),
 | 
| +                           kInvalidCompressedImage);
 | 
| +  }
 | 
| +
 | 
|    GLboolean reference_settings[2] = { GL_TRUE, GL_FALSE };
 | 
|    for (int x = 0; x < 2; ++x) {
 | 
|      GLboolean setting = reference_settings[x];
 | 
| @@ -281,7 +357,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|  
 | 
|      glActiveTexture(GL_TEXTURE1 + x);
 | 
|  
 | 
| -    glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +    if (copy_type == TexImage) {
 | 
| +      glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                      textures_[1]);
 | 
| +    } else {
 | 
| +      glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                         textures_[1], 0, 0, 0, 0, 4, 4);
 | 
| +    }
 | 
|      EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
|  
 | 
|      EXPECT_EQ(setting, glIsEnabled(GL_DEPTH_TEST));
 | 
| @@ -311,13 +393,15 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, BasicStatePreservation) {
 | 
|  
 | 
|  // Verify that invocation of the extension does not modify the bound
 | 
|  // texture state.
 | 
| -TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
| +TEST_P(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
|      LOG(INFO) <<
 | 
|          "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| +  CopyType copy_type = GetParam();
 | 
| +
 | 
|    glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| @@ -334,6 +418,13 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
|    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
|  
 | 
| +  if (copy_type == TexSubImage) {
 | 
| +    glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                           4, 4, 0,
 | 
| +                           sizeof(kInvalidCompressedImage),
 | 
| +                           kInvalidCompressedImage);
 | 
| +  }
 | 
| +
 | 
|    GLuint texture_ids[2];
 | 
|    glGenTextures(2, texture_ids);
 | 
|  
 | 
| @@ -343,7 +434,12 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    glActiveTexture(GL_TEXTURE1);
 | 
|    glBindTexture(GL_TEXTURE_2D, texture_ids[1]);
 | 
|  
 | 
| -  glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  if (copy_type == TexImage) {
 | 
| +    glCompressedCopyTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1]);
 | 
| +  } else {
 | 
| +    glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                       textures_[1], 0, 0, 0, 0, 4, 4);
 | 
| +  }
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  
 | 
|    GLint active_texture = 0;
 | 
| @@ -366,4 +462,253 @@ TEST_F(GLCompressedCopyTextureCHROMIUMTest, TextureStatePreserved) {
 | 
|    EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
|  }
 | 
|  
 | 
| +TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTextureDimension) {
 | 
| +  if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
| +    LOG(INFO) <<
 | 
| +        "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kCompressedImageDXT1RGB),
 | 
| +                         kCompressedImageDXT1RGB);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  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);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 4, 4, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
| +
 | 
| +  // Reset the destination texture as it might have been converted to RGBA.
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  // xoffset < 0
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     -4, 4, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
| +
 | 
| +  // x < 0
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     4, 4, -4, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
| +
 | 
| +  // xoffset + width > dest_width
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     8, 8, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
| +
 | 
| +  // x + width > source_width
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     0, 0, 8, 8, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_VALUE);
 | 
| +
 | 
| +  // xoffset not within block-boundary
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     3, 0, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
 | 
| +
 | 
| +  // x not within block-boundary
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0], textures_[1],
 | 
| +                                     0, 0, 3, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_INVALID_OPERATION);
 | 
| +}
 | 
| +
 | 
| +TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTextureOffset) {
 | 
| +  if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
| +    LOG(INFO) <<
 | 
| +        "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kCompressedImageDXT1RGB),
 | 
| +                         kCompressedImageDXT1RGB);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  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);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  // Load shader program.
 | 
| +  GLuint program = LoadProgram();
 | 
| +  ASSERT_NE(program, 0u);
 | 
| +  GLint position_loc = glGetAttribLocation(program, "a_position");
 | 
| +  GLint texture_loc = glGetUniformLocation(program, "u_texture");
 | 
| +  ASSERT_NE(position_loc, -1);
 | 
| +  ASSERT_NE(texture_loc, -1);
 | 
| +  glUseProgram(program);
 | 
| +
 | 
| +  // Load geometry.
 | 
| +  GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
 | 
| +  ASSERT_NE(vbo, 0u);
 | 
| +
 | 
| +  // Load texture.
 | 
| +  glActiveTexture(GL_TEXTURE0);
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  glUniform1i(texture_loc, 0);
 | 
| +
 | 
| +  const uint8 kBlack[1 * 4] = {0u, 0u, 0u, 255u};
 | 
| +  const uint8 kRed[1 * 4] = {255u, 0u, 0u, 255u};
 | 
| +  const uint8 kGreen[1 * 4] = {0u, 255u, 0u, 255u};
 | 
| +  const uint8 kBlue[1 * 4] = {0u, 0u, 255u, 255u};
 | 
| +
 | 
| +  // Copy each block one by one in a clockwise fashion. Note that we reset the
 | 
| +  // destination texture after each copy operation. That's because on some
 | 
| +  // platforms we might fallback into replacing the compressed destination
 | 
| +  // texture with an uncompressed one.
 | 
| +
 | 
| +  // Move blue block up.
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 0, 0, 0, 4, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glDrawArrays(GL_TRIANGLES, 0, 6);
 | 
| +  glFlush();
 | 
| +  GLTestHelper::CheckPixels(0, 0, 2, 2, 0, kBlue);
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  // Move red block right.
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 4, 0, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glDrawArrays(GL_TRIANGLES, 0, 6);
 | 
| +  glFlush();
 | 
| +  GLTestHelper::CheckPixels(2, 0, 2, 2, 0, kRed);
 | 
| +
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  // Move green block down.
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 4, 4, 4, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glDrawArrays(GL_TRIANGLES, 0, 6);
 | 
| +  glFlush();
 | 
| +  GLTestHelper::CheckPixels(2, 2, 2, 2, 0, kGreen);
 | 
| +
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kInvalidCompressedImageLarge),
 | 
| +                         kInvalidCompressedImageLarge);
 | 
| +
 | 
| +  // Move black block left.
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 0, 4, 4, 4, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glDrawArrays(GL_TRIANGLES, 0, 6);
 | 
| +  glFlush();
 | 
| +  GLTestHelper::CheckPixels(0, 2, 2, 2, 0, kBlack);
 | 
| +
 | 
| +  EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
| +}
 | 
| +
 | 
| +TEST_F(GLCompressedCopyTextureCHROMIUMTest, CopySubTexturePreservation) {
 | 
| +  if (!GLTestHelper::HasExtension("GL_EXT_texture_compression_dxt1")) {
 | 
| +    LOG(INFO) <<
 | 
| +        "GL_EXT_texture_compression_dxt1 not supported. Skipping test...";
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[0]);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
| +  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         4, 4, 0,
 | 
| +                         sizeof(kCompressedImageDXT1),
 | 
| +                         kCompressedImageDXT1);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  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);
 | 
| +  glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
 | 
| +                         8, 8, 0,
 | 
| +                         sizeof(kCompressedImageDXT1RGB),
 | 
| +                         kCompressedImageDXT1RGB);
 | 
| +
 | 
| +  // Copy entire first texture into the second, replacing the green block:
 | 
| +  // [R][R]
 | 
| +  // [B][b]
 | 
| +  glCompressedCopySubTextureCHROMIUM(GL_TEXTURE_2D, textures_[0],
 | 
| +                                     textures_[1], 4, 0, 0, 0, 4, 4);
 | 
| +  EXPECT_TRUE(glGetError() == GL_NO_ERROR);
 | 
| +
 | 
| +  // Load shader program.
 | 
| +  GLuint program = LoadProgram();
 | 
| +  ASSERT_NE(program, 0u);
 | 
| +  GLint position_loc = glGetAttribLocation(program, "a_position");
 | 
| +  GLint texture_loc = glGetUniformLocation(program, "u_texture");
 | 
| +  ASSERT_NE(position_loc, -1);
 | 
| +  ASSERT_NE(texture_loc, -1);
 | 
| +  glUseProgram(program);
 | 
| +
 | 
| +  // Load geometry.
 | 
| +  GLuint vbo = GLTestHelper::SetupUnitQuad(position_loc);
 | 
| +  ASSERT_NE(vbo, 0u);
 | 
| +
 | 
| +  // Load texture.
 | 
| +  glActiveTexture(GL_TEXTURE0);
 | 
| +  glBindTexture(GL_TEXTURE_2D, textures_[1]);
 | 
| +  glUniform1i(texture_loc, 0);
 | 
| +
 | 
| +  // Draw.
 | 
| +  glDrawArrays(GL_TRIANGLES, 0, 6);
 | 
| +  glFlush();
 | 
| +
 | 
| +  const uint8 kBlack[1 * 4] = {0u, 0u, 0u, 255u};
 | 
| +  const uint8 kRed[1 * 4] = {255u, 0u, 0u, 255u};
 | 
| +  const uint8 kBlue[1 * 4] = {0u, 0u, 255u, 255u};
 | 
| +
 | 
| +  // Note that while destination texture is 8 x 8 pixels the viewport is only
 | 
| +  // 4 x 4.
 | 
| +  GLTestHelper::CheckPixels(0, 0, 4, 2, 0, kRed);
 | 
| +  GLTestHelper::CheckPixels(0, 2, 2, 2, 0, kBlue);
 | 
| +  GLTestHelper::CheckPixels(2, 2, 2, 2, 0, kBlack);
 | 
| +  EXPECT_TRUE(GL_NO_ERROR == glGetError());
 | 
| +}
 | 
| +
 | 
|  }  // namespace gpu
 | 
| 
 |