Fix validation of ReadPixels format and type.
The validation for ReadPixels allows for two combations of format/type:
1. Based on the current framebuffer's component type.
* GL_RGBA/GL_UNSIGNED_BYTE if the framebuffer is a normalized (signed
or unsigned).
* GL_RGBA_INTEGER/GL_INTEGER if the framebuffer is an
integer format.
* GL_RGBA_INTEGER/GL_UNSIGNED_INTEGER if the framebuffer is an
unsigned integer format.
* GL_RGBA/GL_FLOAT if the framebuffer is any type of float
framebuffer (added in EXT_color_buffer_float).
* These combations are detailed in the ES2 spec on pg 105 or ES3 on pg
193.
2. The implementation read format/type returned from glGetIntegerv.
* These formats are added by specs, OES_texture_float, EXT_texture_rg,
EXT_read_format_bgra, etc.
Update the GL and D3D backends to perform the conversion from GL_HALF_FLOAT
to GL_HALF_FLOAT_OES.
Continue allowing reading as BGRA_EXT to support Skia. Should be removed in
the future.
BUG=607283
BUG=angleproject:1478
Change-Id: I0312cad4d5f138ab036f383d221f8ccd19a77f6d
Reviewed-on: https://chromium-review.googlesource.com/346232
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 0d52428..067b224 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -352,6 +352,26 @@
(luminanceBits + alphaBits) > 0);
}
+GLenum InternalFormat::getReadPixelsFormat() const
+{
+ return format;
+}
+
+GLenum InternalFormat::getReadPixelsType() const
+{
+ switch (type)
+ {
+ case GL_HALF_FLOAT:
+ // The internal format may have a type of GL_HALF_FLOAT but when exposing this type as
+ // the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by
+ // OES_texture_half_float
+ return GL_HALF_FLOAT_OES;
+
+ default:
+ return type;
+ }
+}
+
Format::Format(GLenum internalFormat) : Format(GetInternalFormatInfo(internalFormat))
{
}
diff --git a/src/libANGLE/formatutils.h b/src/libANGLE/formatutils.h
index 24956c6..b5dc6a4 100644
--- a/src/libANGLE/formatutils.h
+++ b/src/libANGLE/formatutils.h
@@ -76,6 +76,8 @@
const gl::PixelUnpackState &unpack,
bool applySkipImages) const;
bool isLUMA() const;
+ GLenum getReadPixelsFormat() const;
+ GLenum getReadPixelsType() const;
bool operator==(const InternalFormat &other) const;
bool operator!=(const InternalFormat &other) const;
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index a45c945..a272264 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -207,7 +207,7 @@
GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
- return implementationFormatInfo.format;
+ return implementationFormatInfo.getReadPixelsFormat();
}
GLenum FramebufferD3D::getImplementationColorReadType() const
@@ -229,7 +229,7 @@
GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
- return implementationFormatInfo.type;
+ return implementationFormatInfo.getReadPixelsType();
}
gl::Error FramebufferD3D::readPixels(ContextImpl *context,
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 4606114..8d84c60 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -21,6 +21,7 @@
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/TextureGL.h"
#include "libANGLE/renderer/gl/WorkaroundsGL.h"
+#include "libANGLE/renderer/gl/formatutilsgl.h"
#include "platform/Platform.h"
using namespace gl;
@@ -212,14 +213,14 @@
{
const auto *readAttachment = mState.getReadAttachment();
const Format &format = readAttachment->getFormat();
- return format.info->format;
+ return format.info->getReadPixelsFormat();
}
GLenum FramebufferGL::getImplementationColorReadType() const
{
const auto *readAttachment = mState.getReadAttachment();
const Format &format = readAttachment->getFormat();
- return format.info->type;
+ return format.info->getReadPixelsType();
}
Error FramebufferGL::readPixels(ContextImpl *context,
@@ -234,7 +235,11 @@
mStateManager->setPixelPackState(packState);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
- mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels);
+
+ nativegl::ReadPixelsFormat readPixelsFormat =
+ nativegl::GetReadPixelsFormat(mFunctions, mWorkarounds, format, type);
+ mFunctions->readPixels(area.x, area.y, area.width, area.height, readPixelsFormat.format,
+ readPixelsFormat.type, pixels);
return Error(GL_NO_ERROR);
}
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.cpp b/src/libANGLE/renderer/gl/formatutilsgl.cpp
index 1688be1..c5219b4 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.cpp
+++ b/src/libANGLE/renderer/gl/formatutilsgl.cpp
@@ -438,6 +438,32 @@
return result;
}
+static GLenum GetNativeReadType(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum type)
+{
+ GLenum result = type;
+
+ if (functions->standard == STANDARD_GL_DESKTOP)
+ {
+ if (type == GL_HALF_FLOAT_OES)
+ {
+ // The enums differ for the OES half float extensions and desktop GL spec. Update it.
+ result = GL_HALF_FLOAT;
+ }
+ }
+
+ return result;
+}
+
+static GLenum GetNativeReadFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format)
+{
+ GLenum result = format;
+ return result;
+}
+
TexImageFormat GetTexImageFormat(const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
GLenum internalFormat,
@@ -512,6 +538,16 @@
GetNativeInternalFormat(functions, workarounds, internalFormat, internalFormat);
return result;
}
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type)
+{
+ ReadPixelsFormat result;
+ result.format = GetNativeReadFormat(functions, workarounds, format);
+ result.type = GetNativeReadType(functions, workarounds, type);
+ return result;
+}
}
}
diff --git a/src/libANGLE/renderer/gl/formatutilsgl.h b/src/libANGLE/renderer/gl/formatutilsgl.h
index 547d478..616f37a 100644
--- a/src/libANGLE/renderer/gl/formatutilsgl.h
+++ b/src/libANGLE/renderer/gl/formatutilsgl.h
@@ -112,6 +112,16 @@
RenderbufferFormat GetRenderbufferFormat(const FunctionsGL *functions,
const WorkaroundsGL &workarounds,
GLenum internalFormat);
+
+struct ReadPixelsFormat
+{
+ GLenum format;
+ GLenum type;
+};
+ReadPixelsFormat GetReadPixelsFormat(const FunctionsGL *functions,
+ const WorkaroundsGL &workarounds,
+ GLenum format,
+ GLenum type);
}
}
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 0846f0d..d204d67 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -99,6 +99,38 @@
return true;
}
+bool ValidReadPixelsFormatType(ValidationContext *context,
+ GLenum framebufferComponentType,
+ GLenum format,
+ GLenum type)
+{
+ switch (framebufferComponentType)
+ {
+ case GL_UNSIGNED_NORMALIZED:
+ // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
+ // ReadPixels with BGRA even if the extension is not present
+ return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
+ (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_BYTE);
+
+ case GL_SIGNED_NORMALIZED:
+ return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
+
+ case GL_INT:
+ return (format == GL_RGBA_INTEGER && type == GL_INT);
+
+ case GL_UNSIGNED_INT:
+ return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
+
+ case GL_FLOAT:
+ return (format == GL_RGBA && type == GL_FLOAT);
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
} // anonymous namespace
bool ValidCap(const Context *context, GLenum cap)
@@ -1122,12 +1154,12 @@
GLenum currentFormat = framebuffer->getImplementationColorReadFormat();
GLenum currentType = framebuffer->getImplementationColorReadType();
GLenum currentInternalFormat = readBuffer->getFormat().asSized();
- GLuint clientVersion = context->getClientMajorVersion();
- bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
- ValidES3ReadFormatType(context, currentInternalFormat, format, type);
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(currentInternalFormat);
+ bool validFormatTypeCombination =
+ ValidReadPixelsFormatType(context, internalFormatInfo.componentType, format, type);
- if (!(currentFormat == format && currentType == type) && !validReadFormat)
+ if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 68285ce..e329fd0 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -1187,52 +1187,6 @@
return true;
}
-// check for combinations of format and type that are valid for ReadPixels
-bool ValidES2ReadFormatType(ValidationContext *context, GLenum format, GLenum type)
-{
- switch (format)
- {
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- break;
- default:
- return false;
- }
- break;
- case GL_BGRA_EXT:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
- break;
- default:
- return false;
- }
- break;
- case GL_RG_EXT:
- case GL_RED_EXT:
- if (!context->getExtensions().textureRG)
- {
- return false;
- }
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- break;
- default:
- return false;
- }
- break;
-
- default:
- return false;
- }
- return true;
-}
-
bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
const GLenum *attachments)
{
diff --git a/src/libANGLE/validationES2.h b/src/libANGLE/validationES2.h
index 1ebb262..4e6be10 100644
--- a/src/libANGLE/validationES2.h
+++ b/src/libANGLE/validationES2.h
@@ -38,8 +38,6 @@
bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat,
GLsizei width, GLsizei height);
-bool ValidES2ReadFormatType(ValidationContext *context, GLenum format, GLenum type);
-
bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments,
const GLenum *attachments);
diff --git a/src/libANGLE/validationES3.cpp b/src/libANGLE/validationES3.cpp
index c6f645c..c891563 100644
--- a/src/libANGLE/validationES3.cpp
+++ b/src/libANGLE/validationES3.cpp
@@ -204,6 +204,7 @@
InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES );
InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT );
InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT );
+ // clang-format on
// From GL_EXT_texture_norm16
InsertES3FormatCombo(&set, GL_R16_EXT, GL_RED, GL_UNSIGNED_SHORT);
@@ -214,7 +215,6 @@
InsertES3FormatCombo(&set, GL_RG16_SNORM_EXT, GL_RG, GL_SHORT);
InsertES3FormatCombo(&set, GL_RGB16_SNORM_EXT, GL_RGB, GL_SHORT);
InsertES3FormatCombo(&set, GL_RGBA16_SNORM_EXT, GL_RGBA, GL_SHORT);
- // clang-format on
return set;
}
@@ -1271,100 +1271,6 @@
return true;
}
-bool ValidES3ReadFormatType(ValidationContext *context,
- GLenum internalFormat,
- GLenum format,
- GLenum type)
-{
- const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat);
-
- switch (format)
- {
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- break;
- case GL_UNSIGNED_SHORT:
- if (internalFormatInfo.componentType != GL_UNSIGNED_NORMALIZED &&
- internalFormatInfo.type != GL_UNSIGNED_SHORT)
- {
- return false;
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- if (internalFormat != GL_RGB10_A2)
- {
- return false;
- }
- break;
- case GL_FLOAT:
- if (internalFormatInfo.componentType != GL_FLOAT)
- {
- return false;
- }
- break;
- default:
- return false;
- }
- break;
- case GL_RGBA_INTEGER:
- switch (type)
- {
- case GL_INT:
- if (internalFormatInfo.componentType != GL_INT)
- {
- return false;
- }
- break;
- case GL_UNSIGNED_INT:
- if (internalFormatInfo.componentType != GL_UNSIGNED_INT)
- {
- return false;
- }
- break;
- default:
- return false;
- }
- break;
- case GL_BGRA_EXT:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
- break;
- default:
- return false;
- }
- break;
- case GL_RG_EXT:
- case GL_RED_EXT:
- if (!context->getExtensions().textureRG)
- {
- return false;
- }
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- break;
- case GL_UNSIGNED_SHORT:
- if (internalFormatInfo.componentType != GL_UNSIGNED_NORMALIZED &&
- internalFormatInfo.type != GL_UNSIGNED_SHORT)
- {
- return false;
- }
- break;
- default:
- return false;
- }
- break;
- default:
- return false;
- }
- return true;
-}
-
bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height)
{
diff --git a/src/libANGLE/validationES3.h b/src/libANGLE/validationES3.h
index eeef800..7e8712b 100644
--- a/src/libANGLE/validationES3.h
+++ b/src/libANGLE/validationES3.h
@@ -153,11 +153,6 @@
bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer);
-bool ValidES3ReadFormatType(ValidationContext *context,
- GLenum internalFormat,
- GLenum format,
- GLenum type);
-
bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
diff --git a/src/tests/gl_tests/BlendMinMaxTest.cpp b/src/tests/gl_tests/BlendMinMaxTest.cpp
index 8ccaf92..39f5251 100644
--- a/src/tests/gl_tests/BlendMinMaxTest.cpp
+++ b/src/tests/gl_tests/BlendMinMaxTest.cpp
@@ -32,13 +32,12 @@
float values[4];
};
- static GLubyte getExpected(bool blendMin, float curColor, GLubyte prevColor)
+ static float getExpected(bool blendMin, float curColor, float prevColor)
{
- GLubyte curAsUbyte = static_cast<GLubyte>((curColor * std::numeric_limits<GLubyte>::max()) + 0.5f);
- return blendMin ? std::min<GLubyte>(curAsUbyte, prevColor) : std::max<GLubyte>(curAsUbyte, prevColor);
+ return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor);
}
- void runTest(GLenum colorFormat)
+ void runTest(GLenum colorFormat, GLenum type)
{
if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_blend_minmax"))
{
@@ -55,17 +54,26 @@
SetUpFramebuffer(colorFormat);
- const size_t colorCount = 1024;
+ int minValue = 0;
+ int maxValue = 1;
+ if (type == GL_FLOAT)
+ {
+ minValue = -1024;
+ maxValue = 1024;
+ }
+
+ const size_t colorCount = 128;
Color colors[colorCount];
for (size_t i = 0; i < colorCount; i++)
{
for (size_t j = 0; j < 4; j++)
{
- colors[i].values[j] = (rand() % 255) / 255.0f;
+ colors[i].values[j] =
+ static_cast<float>(minValue + (rand() % (maxValue - minValue)));
}
}
- GLubyte prevColor[4];
+ float prevColor[4];
for (size_t i = 0; i < colorCount; i++)
{
const Color &color = colors[i];
@@ -77,16 +85,37 @@
drawQuad(mProgram, "aPosition", 0.5f);
- if (i > 0)
+ float pixel[4];
+ if (type == GL_UNSIGNED_BYTE)
{
- EXPECT_PIXEL_EQ(0, 0,
- getExpected(blendMin, color.values[0], prevColor[0]),
- getExpected(blendMin, color.values[1], prevColor[1]),
- getExpected(blendMin, color.values[2], prevColor[2]),
- getExpected(blendMin, color.values[3], prevColor[3]));
+ GLubyte ubytePixel[4];
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel);
+ for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+ {
+ pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f;
+ }
+ }
+ else if (type == GL_FLOAT)
+ {
+ glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
+ }
+ else
+ {
+ FAIL() << "Unexpected pixel type";
}
- glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, prevColor);
+ if (i > 0)
+ {
+ const float errorRange = 1.0f / 255.0f;
+ for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
+ {
+ EXPECT_NEAR(
+ getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]),
+ pixel[componentIdx], errorRange);
+ }
+ }
+
+ memcpy(prevColor, pixel, sizeof(pixel));
}
}
@@ -142,6 +171,9 @@
glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
ASSERT_GL_NO_ERROR();
}
@@ -163,10 +195,10 @@
TEST_P(BlendMinMaxTest, RGBA8)
{
- runTest(GL_RGBA8);
+ runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
}
-TEST_P(BlendMinMaxTest, RGBA32f)
+TEST_P(BlendMinMaxTest, RGBA32F)
{
if (getClientMajorVersion() < 3 || !extensionEnabled("GL_EXT_color_buffer_float"))
{
@@ -189,7 +221,7 @@
return;
}
- runTest(GL_RGBA32F);
+ runTest(GL_RGBA32F, GL_FLOAT);
}
TEST_P(BlendMinMaxTest, RGBA16F)
@@ -208,21 +240,16 @@
return;
}
- // TODO(geofflang): This fails because readpixels with UNSIGNED_BYTE/RGBA does not work with
- // half float buffers (http://anglebug.com/1288)
- if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
- {
- std::cout << "Test skipped on OpenGL ES targets." << std::endl;
- return;
- }
-
- runTest(GL_RGBA16F);
+ runTest(GL_RGBA16F, GL_FLOAT);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(BlendMinMaxTest,
ES2_D3D9(),
ES2_D3D11(),
+ ES3_D3D11(),
ES2_D3D11_FL9_3(),
ES2_OPENGL(),
- ES2_OPENGLES());
+ ES3_OPENGL(),
+ ES2_OPENGLES(),
+ ES3_OPENGLES());
diff --git a/src/tests/gl_tests/TextureTest.cpp b/src/tests/gl_tests/TextureTest.cpp
index ba045af..9d38ad7 100644
--- a/src/tests/gl_tests/TextureTest.cpp
+++ b/src/tests/gl_tests/TextureTest.cpp
@@ -14,24 +14,24 @@
{
// Take a pixel, and reset the components not covered by the format to default
-// values. In particular, the default value for the alpha component is 65535
+// values. In particular, the default value for the alpha component is 255
// (1.0 as unsigned normalized fixed point value).
-GLColor16 SliceFormatColor16(GLenum format, GLColor16 full)
+GLColor SliceFormatColor(GLenum format, GLColor full)
{
switch (format)
{
case GL_RED:
- return GLColor16(full.R, 0, 0, 65535u);
+ return GLColor(full.R, 0, 0, 255u);
case GL_RG:
- return GLColor16(full.R, full.G, 0, 65535u);
+ return GLColor(full.R, full.G, 0, 255u);
case GL_RGB:
- return GLColor16(full.R, full.G, full.B, 65535u);
+ return GLColor(full.R, full.G, full.B, 255u);
case GL_RGBA:
return full;
default:
UNREACHABLE();
+ return GLColor::white;
}
- return GLColor16::white;
}
class TexCoordDrawTest : public ANGLETest
@@ -3248,8 +3248,8 @@
void testNorm16Texture(GLint internalformat, GLenum format, GLenum type)
{
- GLushort pixelValue = type == GL_SHORT ? 0x7FFF : 0x6A35;
- GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
+ GLushort pixelValue = (type == GL_SHORT) ? 0x7FFF : 0x6A35;
+ GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
setUpProgram();
@@ -3261,20 +3261,17 @@
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16_EXT, 1, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT, nullptr);
glBindTexture(GL_TEXTURE_2D, mTextures[1]);
- glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
+ glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
EXPECT_GL_NO_ERROR();
drawQuad(mProgram, "position", 0.5f);
- GLColor16 expectedValue = imageData;
- if (type == GL_SHORT)
- {
- // sampled as signed value; then stored as unsigned value
- expectedValue = GLColor16::white;
- }
+ GLubyte expectedValue = (type == GL_SHORT) ? 0xFF : static_cast<GLubyte>(pixelValue >> 8);
- EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
+ EXPECT_PIXEL_COLOR_EQ(
+ 0, 0, SliceFormatColor(
+ format, GLColor(expectedValue, expectedValue, expectedValue, expectedValue)));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -3284,7 +3281,7 @@
void testNorm16Render(GLint internalformat, GLenum format, GLenum type)
{
GLushort pixelValue = 0x6A35;
- GLColor16 imageData(pixelValue, pixelValue, pixelValue, pixelValue);
+ GLushort imageData[] = {pixelValue, pixelValue, pixelValue, pixelValue};
setUpProgram();
@@ -3296,13 +3293,16 @@
0);
glBindTexture(GL_TEXTURE_2D, mTextures[2]);
- glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, &imageData.R);
+ glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, type, imageData);
EXPECT_GL_NO_ERROR();
drawQuad(mProgram, "position", 0.5f);
- EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, imageData));
+ GLubyte expectedValue = static_cast<GLubyte>(pixelValue >> 8);
+ EXPECT_PIXEL_COLOR_EQ(
+ 0, 0, SliceFormatColor(
+ format, GLColor(expectedValue, expectedValue, expectedValue, expectedValue)));
glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
@@ -3316,8 +3316,7 @@
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
- GLColor16 expectedValue = GLColor16::white;
- EXPECT_PIXEL_COLOR16_EQ(0, 0, SliceFormatColor16(format, expectedValue));
+ EXPECT_PIXEL_COLOR_EQ(0, 0, SliceFormatColor(format, GLColor::white));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp
index 7bec1e1..d99c25e 100644
--- a/src/tests/test_utils/ANGLETest.cpp
+++ b/src/tests/test_utils/ANGLETest.cpp
@@ -30,8 +30,6 @@
const GLColor GLColor::white = GLColor(255u, 255u, 255u, 255u);
const GLColor GLColor::yellow = GLColor(255u, 255u, 0, 255u);
-const GLColor16 GLColor16::white = GLColor16(65535u, 65535u, 65535u, 65535u);
-
namespace
{
float ColorNorm(GLubyte channelValue)
@@ -138,14 +136,6 @@
{
}
-GLColor::GLColor(const GLColor16 &color16)
- : R(static_cast<GLubyte>(color16.R)),
- G(static_cast<GLubyte>(color16.G)),
- B(static_cast<GLubyte>(color16.B)),
- A(static_cast<GLubyte>(color16.A))
-{
-}
-
GLColor::GLColor(GLuint colorValue) : R(0), G(0), B(0), A(0)
{
memcpy(&R, &colorValue, sizeof(GLuint));
@@ -177,35 +167,6 @@
return ostream;
}
-GLColor16::GLColor16() : R(0), G(0), B(0), A(0)
-{
-}
-
-GLColor16::GLColor16(GLushort r, GLushort g, GLushort b, GLushort a) : R(r), G(g), B(b), A(a)
-{
-}
-
-GLColor16 ReadColor16(GLint x, GLint y)
-{
- GLColor16 actual;
- glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, &actual.R);
- EXPECT_GL_NO_ERROR();
- return actual;
-}
-
-bool operator==(const GLColor16 &a, const GLColor16 &b)
-{
- return a.R == b.R && a.G == b.G && a.B == b.B && a.A == b.A;
-}
-
-std::ostream &operator<<(std::ostream &ostream, const GLColor16 &color)
-{
- ostream << "(" << static_cast<unsigned int>(color.R) << ", "
- << static_cast<unsigned int>(color.G) << ", " << static_cast<unsigned int>(color.B)
- << ", " << static_cast<unsigned int>(color.A) << ")";
- return ostream;
-}
-
} // namespace angle
// static
diff --git a/src/tests/test_utils/ANGLETest.h b/src/tests/test_utils/ANGLETest.h
index 73b69cd..ffe46fa 100644
--- a/src/tests/test_utils/ANGLETest.h
+++ b/src/tests/test_utils/ANGLETest.h
@@ -59,14 +59,11 @@
static const GLColorRGB yellow;
};
-struct GLColor16;
-
struct GLColor
{
GLColor();
GLColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
GLColor(const Vector4 &floatColor);
- GLColor(const GLColor16 &color16);
GLColor(GLuint colorValue);
Vector4 toNormalizedVector() const;
@@ -95,28 +92,6 @@
std::ostream &operator<<(std::ostream &ostream, const GLColor &color);
GLColor ReadColor(GLint x, GLint y);
-struct GLColor16
-{
- GLColor16();
- GLColor16(GLushort r, GLushort g, GLushort b, GLushort a);
-
- GLushort R, G, B, A;
-
- static const GLColor16 white;
-};
-
-// Useful to cast any type to GLushort.
-template <typename TR, typename TG, typename TB, typename TA>
-GLColor16 MakeGLColor16(TR r, TG g, TB b, TA a)
-{
- return GLColor16(static_cast<GLushort>(r), static_cast<GLushort>(g), static_cast<GLushort>(b),
- static_cast<GLushort>(a));
-}
-
-bool operator==(const GLColor16 &a, const GLColor16 &b);
-std::ostream &operator<<(std::ostream &ostream, const GLColor16 &color);
-GLColor16 ReadColor16(GLint x, GLint y);
-
} // namespace angle
#define EXPECT_PIXEL_EQ(x, y, r, g, b, a) \
@@ -141,8 +116,6 @@
#define EXPECT_PIXEL_COLOR_NEAR(x, y, angleColor, abs_error) \
EXPECT_PIXEL_NEAR(x, y, angleColor.R, angleColor.G, angleColor.B, angleColor.A, abs_error)
-#define EXPECT_PIXEL_COLOR16_EQ(x, y, angleColor) EXPECT_EQ(angleColor, angle::ReadColor16(x, y))
-
#define EXPECT_COLOR_NEAR(expected, actual, abs_error) \
\
{ \