blob: bd5e72e2d0dd76a0d4f73ae20049ded3a0886c01 [file] [log] [blame]
//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CopyTextureTest.cpp: Tests of the GL_CHROMIUM_copy_texture extension
#include "test_utils/ANGLETest.h"
namespace angle
{
class CopyTextureTest : public ANGLETest
{
protected:
CopyTextureTest()
{
setWindowWidth(256);
setWindowHeight(256);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
void SetUp() override
{
ANGLETest::SetUp();
glGenTextures(2, mTextures);
glBindTexture(GL_TEXTURE_2D, mTextures[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);
glGenFramebuffers(1, &mFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1],
0);
if (extensionEnabled("GL_CHROMIUM_copy_texture"))
{
glCopyTextureCHROMIUM = reinterpret_cast<PFNGLCOPYTEXTURECHROMIUMPROC>(
eglGetProcAddress("glCopyTextureCHROMIUM"));
glCopySubTextureCHROMIUM = reinterpret_cast<PFNGLCOPYSUBTEXTURECHROMIUMPROC>(
eglGetProcAddress("glCopySubTextureCHROMIUM"));
}
}
void TearDown() override
{
glDeleteTextures(2, mTextures);
glDeleteFramebuffers(1, &mFramebuffer);
ANGLETest::TearDown();
}
bool checkExtensions() const
{
if (!extensionEnabled("GL_CHROMIUM_copy_texture"))
{
std::cout << "Test skipped because GL_CHROMIUM_copy_texture is not available."
<< std::endl;
return false;
}
EXPECT_NE(nullptr, glCopyTextureCHROMIUM);
EXPECT_NE(nullptr, glCopySubTextureCHROMIUM);
return true;
}
GLuint mTextures[2] = {
0, 0,
};
GLuint mFramebuffer = 0;
PFNGLCOPYTEXTURECHROMIUMPROC glCopyTextureCHROMIUM = nullptr;
PFNGLCOPYSUBTEXTURECHROMIUMPROC glCopySubTextureCHROMIUM = nullptr;
};
// Test to ensure that the basic functionality of the extension works.
TEST_P(CopyTextureTest, BasicCopyTexture)
{
if (!checkExtensions())
{
return;
}
GLColor pixels = GLColor::red;
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
}
// Test to ensure that the basic functionality of the extension works.
TEST_P(CopyTextureTest, BasicCopySubTexture)
{
if (!checkExtensions())
{
return;
}
GLColor pixels = GLColor::red;
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
EXPECT_GL_NO_ERROR();
}
// Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to
// immutable textures
TEST_P(CopyTextureTest, ImmutableTexture)
{
if (!checkExtensions())
{
return;
}
if (getClientMajorVersion() < 3 &&
(!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8")))
{
std::cout
<< "Test skipped due to missing ES3 or GL_EXT_texture_storage or GL_OES_rgb8_rgba8"
<< std::endl;
return;
}
GLColor pixels = GLColor::red;
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
EXPECT_GL_NO_ERROR();
// Should generate an error when the texture is redefined
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// Should succeed when using CopySubTexture
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(0, 0, pixels);
EXPECT_GL_NO_ERROR();
}
// Test validation of internal formats in CopyTexture and CopySubTexture
TEST_P(CopyTextureTest, InternalFormat)
{
if (!checkExtensions())
{
return;
}
std::vector<GLint> sourceFormats;
sourceFormats.push_back(GL_ALPHA);
sourceFormats.push_back(GL_RGB);
sourceFormats.push_back(GL_RGBA);
sourceFormats.push_back(GL_LUMINANCE);
sourceFormats.push_back(GL_LUMINANCE_ALPHA);
std::vector<GLint> destFormats;
destFormats.push_back(GL_RGB);
destFormats.push_back(GL_RGBA);
if (extensionEnabled("GL_EXT_texture_format_BGRA8888"))
{
sourceFormats.push_back(GL_BGRA_EXT);
destFormats.push_back(GL_BGRA_EXT);
}
// Test with glCopyTexture
for (GLint sourceFormat : sourceFormats)
{
for (GLint destFormat : destFormats)
{
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
nullptr);
EXPECT_GL_NO_ERROR();
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, destFormat,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
}
}
// Test with glCopySubTexture
for (GLint sourceFormat : sourceFormats)
{
for (GLint destFormat : destFormats)
{
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE,
nullptr);
EXPECT_GL_NO_ERROR();
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE,
nullptr);
EXPECT_GL_NO_ERROR();
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1,
1, false, false, false);
EXPECT_GL_NO_ERROR();
}
}
}
// Check that invalid internal formats return errors.
TEST_P(CopyTextureTest, InternalFormatNotSupported)
{
if (!checkExtensions())
{
return;
}
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_GL_NO_ERROR();
std::vector<GLint> unsupportedDestFormats;
unsupportedDestFormats.push_back(GL_ALPHA);
unsupportedDestFormats.push_back(GL_LUMINANCE);
unsupportedDestFormats.push_back(GL_LUMINANCE_ALPHA);
if (!extensionEnabled("GL_EXT_texture_format_BGRA8888"))
{
unsupportedDestFormats.push_back(GL_BGRA_EXT);
}
// Check unsupported format reports an error.
for (GLint unsupportedDestFormat : unsupportedDestFormats)
{
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0,
unsupportedDestFormat, GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
for (GLint unsupportedDestFormat : unsupportedDestFormats)
{
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, unsupportedDestFormat, 1, 1, 0, unsupportedDestFormat,
GL_UNSIGNED_BYTE, nullptr);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
}
// Test to ensure that the destination texture is redefined if the properties are different.
TEST_P(CopyTextureTest, RedefineDestinationTexture)
{
if (!checkExtensions())
{
return;
}
GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
EXPECT_GL_NO_ERROR();
// GL_INVALID_OPERATION due to "intrinsic format" != "internal format".
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
// GL_INVALID_VALUE due to bad dimensions.
glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// If the dest texture has different properties, glCopyTextureCHROMIUM()
// redefines them.
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
// glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2
// dimension and GL_RGBA format.
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]);
EXPECT_GL_NO_ERROR();
}
// Test that invalid dimensions in CopySubTexture are validated
TEST_P(CopyTextureTest, CopySubTextureDimension)
{
if (!checkExtensions())
{
return;
}
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
// xoffset < 0
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, -1, 1, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// x < 0
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, -1, 0, 1, 1,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// xoffset + width > dest_width
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 2, 2, 0, 0, 2, 2,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
// x + width > source_width
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 0, 1, 1, 2, 2,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
}
// Test that invalid IDs in CopyTexture are validated
TEST_P(CopyTextureTest, CopyTextureInvalidTextureIds)
{
if (!checkExtensions())
{
return;
}
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, GL_RGBA, GL_UNSIGNED_BYTE,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopyTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA, GL_UNSIGNED_BYTE,
false, false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopyTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, GL_RGBA, GL_UNSIGNED_BYTE, false,
false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
}
// Test that invalid IDs in CopySubTexture are validated
TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds)
{
if (!checkExtensions())
{
return;
}
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, 99993, 0, 1, 1, 0, 0, 1, 1, false,
false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopySubTextureCHROMIUM(99994, 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1, false,
false, false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopySubTextureCHROMIUM(99995, 0, GL_TEXTURE_2D, 99996, 0, 1, 1, 0, 0, 1, 1, false, false,
false);
EXPECT_GL_ERROR(GL_INVALID_VALUE);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
}
// Test that using an offset in CopySubTexture works correctly
TEST_P(CopyTextureTest, CopySubTextureOffset)
{
if (!checkExtensions())
{
return;
}
GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack,
GLColor::transparentBlack, GLColor::transparentBlack};
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels);
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 1, 0, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 1, 0, 1, 0, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
glCopySubTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, 0, 1, 0, 1, 1, 1,
false, false, false);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
EXPECT_GL_NO_ERROR();
}
// Test that flipping the Y component works correctly
TEST_P(CopyTextureTest, FlipY)
{
if (!checkExtensions())
{
return;
}
GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u),
GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, GL_TRUE, GL_FALSE, GL_FALSE);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_EQ(0, 0, rgbaPixels[2]);
EXPECT_PIXEL_COLOR_EQ(1, 0, rgbaPixels[3]);
EXPECT_PIXEL_COLOR_EQ(0, 1, rgbaPixels[0]);
EXPECT_PIXEL_COLOR_EQ(1, 1, rgbaPixels[1]);
EXPECT_GL_NO_ERROR();
}
// Test that premultipying the alpha on copy works correctly
TEST_P(CopyTextureTest, PremultiplyAlpha)
{
if (!checkExtensions())
{
return;
}
GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(255u, 255u, 255u, 127u),
GLColor(127u, 127u, 127u, 127u), GLColor(255u, 255u, 255u, 0u)};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, GL_FALSE, GL_TRUE, GL_FALSE);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(127, 127, 127, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(63, 63, 63, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(0, 0, 0, 0), 1.0);
EXPECT_GL_NO_ERROR();
}
// Test that unmultipying the alpha on copy works correctly
TEST_P(CopyTextureTest, UnmultiplyAlpha)
{
if (!checkExtensions())
{
return;
}
GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u),
GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, GL_TRUE);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(255, 255, 255, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(127, 127, 127, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 255, 255, 0), 1.0);
EXPECT_GL_NO_ERROR();
}
// Test that unmultipying and premultiplying the alpha is the same as doing neither
TEST_P(CopyTextureTest, UnmultiplyAndPremultiplyAlpha)
{
if (!checkExtensions())
{
return;
}
GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u),
GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)};
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, GL_FALSE, GL_TRUE, GL_TRUE);
EXPECT_GL_NO_ERROR();
// Check that FB is complete.
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(127, 127, 127, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(63, 63, 63, 127), 1.0);
EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 255, 255, 0), 1.0);
EXPECT_GL_NO_ERROR();
}
// Test to ensure that CopyTexture works with LUMINANCE_ALPHA texture
TEST_P(CopyTextureTest, LuminanceAlpha)
{
if (!checkExtensions())
{
return;
}
uint8_t originalPixels[] = {163u, 67u};
GLColor expectedPixels(163u, 163u, 163u, 67u);
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1, 1, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, &originalPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
}
// Test to ensure that CopyTexture works with LUMINANCE texture
TEST_P(CopyTextureTest, Luminance)
{
if (!checkExtensions())
{
return;
}
uint8_t originalPixels[] = {57u};
GLColor expectedPixels(57u, 57u, 57u, 255u);
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
&originalPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
}
// Test to ensure that CopyTexture works with ALPHA texture
TEST_P(CopyTextureTest, Alpha)
{
if (!checkExtensions())
{
return;
}
uint8_t originalPixels[] = {77u};
GLColor expectedPixels(0u, 0u, 0u, 77u);
glBindTexture(GL_TEXTURE_2D, mTextures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 1, 1, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &originalPixels);
glCopyTextureCHROMIUM(mTextures[0], 0, GL_TEXTURE_2D, mTextures[1], 0, GL_RGBA,
GL_UNSIGNED_BYTE, false, false, false);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixels);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(CopyTextureTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
} // namespace angle