Commit b10a0dfc by Amy Liu Committed by Commit Bot

Fix flip info of colorBlit with pre-rotation.

Get wrong colorBlit results on android if there is flip operation added by glBlitFramebuffer API. Fix the implementation and add related end2end tests. Bug: angleproject:5044 Change-Id: I797f8858b3943b5effe27261e954ca1405960ef0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2534210 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarIan Elliott <ianelliott@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent fd97c334
...@@ -156,8 +156,10 @@ void AdjustBlitAreaForPreRotation(SurfaceRotation framebufferAngle, ...@@ -156,8 +156,10 @@ void AdjustBlitAreaForPreRotation(SurfaceRotation framebufferAngle,
} }
} }
void AdjustFramebufferDimensionsForPreRotation(SurfaceRotation framebufferAngle, void AdjustDimensionsAndFlipForPreRotation(SurfaceRotation framebufferAngle,
gl::Rectangle *framebufferDimensions) gl::Rectangle *framebufferDimensions,
bool *flipX,
bool *flipY)
{ {
switch (framebufferAngle) switch (framebufferAngle)
{ {
...@@ -166,11 +168,13 @@ void AdjustFramebufferDimensionsForPreRotation(SurfaceRotation framebufferAngle, ...@@ -166,11 +168,13 @@ void AdjustFramebufferDimensionsForPreRotation(SurfaceRotation framebufferAngle,
break; break;
case SurfaceRotation::Rotated90Degrees: case SurfaceRotation::Rotated90Degrees:
std::swap(framebufferDimensions->width, framebufferDimensions->height); std::swap(framebufferDimensions->width, framebufferDimensions->height);
std::swap(*flipX, *flipY);
break; break;
case SurfaceRotation::Rotated180Degrees: case SurfaceRotation::Rotated180Degrees:
break; break;
case SurfaceRotation::Rotated270Degrees: case SurfaceRotation::Rotated270Degrees:
std::swap(framebufferDimensions->width, framebufferDimensions->height); std::swap(framebufferDimensions->width, framebufferDimensions->height);
std::swap(*flipX, *flipY);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -228,17 +232,17 @@ void AdjustBlitResolveParametersForPreRotation(SurfaceRotation framebufferAngle, ...@@ -228,17 +232,17 @@ void AdjustBlitResolveParametersForPreRotation(SurfaceRotation framebufferAngle,
std::swap(params->stretch[0], params->stretch[1]); std::swap(params->stretch[0], params->stretch[1]);
std::swap(params->srcOffset[0], params->srcOffset[1]); std::swap(params->srcOffset[0], params->srcOffset[1]);
std::swap(params->rotatedOffsetFactor[0], params->rotatedOffsetFactor[1]); std::swap(params->rotatedOffsetFactor[0], params->rotatedOffsetFactor[1]);
std::swap(params->flipX, params->flipY);
if (srcFramebufferAngle == framebufferAngle) if (srcFramebufferAngle == framebufferAngle)
{ {
std::swap(params->destOffset[0], params->destOffset[1]); std::swap(params->destOffset[0], params->destOffset[1]);
std::swap(params->stretch[0], params->stretch[1]); std::swap(params->stretch[0], params->stretch[1]);
std::swap(params->flipX, params->flipY);
} }
break; break;
case SurfaceRotation::Rotated180Degrees: case SurfaceRotation::Rotated180Degrees:
ASSERT(!params->flipX && params->flipY); // Combine flip info with api flip.
params->flipX = true; params->flipX = !params->flipX;
params->flipY = false; params->flipY = !params->flipY;
break; break;
case SurfaceRotation::Rotated270Degrees: case SurfaceRotation::Rotated270Degrees:
std::swap(params->stretch[0], params->stretch[1]); std::swap(params->stretch[0], params->stretch[1]);
...@@ -248,9 +252,11 @@ void AdjustBlitResolveParametersForPreRotation(SurfaceRotation framebufferAngle, ...@@ -248,9 +252,11 @@ void AdjustBlitResolveParametersForPreRotation(SurfaceRotation framebufferAngle,
{ {
std::swap(params->stretch[0], params->stretch[1]); std::swap(params->stretch[0], params->stretch[1]);
} }
ASSERT(!params->flipX && !params->flipY); // Combine flip info with api flip.
params->flipX = true; params->flipX = !params->flipX;
params->flipY = true; params->flipY = !params->flipY;
std::swap(params->flipX, params->flipY);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -1008,8 +1014,8 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ...@@ -1008,8 +1014,8 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
destFramebufferDimensions.height - srcClippedDestArea.y - srcClippedDestArea.height; destFramebufferDimensions.height - srcClippedDestArea.y - srcClippedDestArea.height;
} }
const bool flipX = sourceArea.isReversedX() != destArea.isReversedX(); bool flipX = sourceArea.isReversedX() != destArea.isReversedX();
const bool flipY = sourceArea.isReversedY() != destArea.isReversedY(); bool flipY = sourceArea.isReversedY() != destArea.isReversedY();
// GLES doesn't allow flipping the parameters of glBlitFramebuffer if performing a resolve. // GLES doesn't allow flipping the parameters of glBlitFramebuffer if performing a resolve.
ASSERT(!isResolve || ASSERT(!isResolve ||
...@@ -1029,8 +1035,8 @@ angle::Result FramebufferVk::blit(const gl::Context *context, ...@@ -1029,8 +1035,8 @@ angle::Result FramebufferVk::blit(const gl::Context *context,
{ {
AdjustBlitAreaForPreRotation(srcFramebufferRotation, sourceAreaOld, AdjustBlitAreaForPreRotation(srcFramebufferRotation, sourceAreaOld,
srcFramebufferDimensions, &sourceArea); srcFramebufferDimensions, &sourceArea);
AdjustFramebufferDimensionsForPreRotation(srcFramebufferRotation, AdjustDimensionsAndFlipForPreRotation(srcFramebufferRotation, &srcFramebufferDimensions,
&srcFramebufferDimensions); &flipX, &flipY);
} }
SurfaceRotation rememberDestFramebufferRotation = destFramebufferRotation; SurfaceRotation rememberDestFramebufferRotation = destFramebufferRotation;
if (srcFramebufferRotation == SurfaceRotation::Rotated90Degrees) if (srcFramebufferRotation == SurfaceRotation::Rotated90Degrees)
......
...@@ -995,16 +995,16 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithRotation) ...@@ -995,16 +995,16 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithRotation)
EXPECT_PIXEL_COLOR_EQ(32, 127, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(32, 127, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(32, 0, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(32, 0, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(63, 0, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(63, 0, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(63, 1, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(63, 64, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(63, 64, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(32, 64, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(32, 64, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(63, 127, GLColor::blue);
// Some pixels around x=0 still fail on android.There are other issues to fix. // Some pixels around x=0/63 (related to the pre-rotation degree) still fail on android.
// From the image in the window, the failures near one of the image's edge look like "aliasing". // From the image in the window, the failures near one of the image's edge look like "aliasing".
// We need to fix blit with pre-rotation. http://anglebug.com/5044 // We need to fix blit with pre-rotation. http://anglebug.com/5044
// EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); // EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(0, 64, GLColor::blue); // EXPECT_PIXEL_COLOR_EQ(0, 64, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(63, 1, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(63, 127, GLColor::blue);
eglSwapBuffers(mDisplay, mWindowSurface); eglSwapBuffers(mDisplay, mWindowSurface);
...@@ -1080,17 +1080,20 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleStencilWithRotation) ...@@ -1080,17 +1080,20 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleStencilWithRotation)
drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f); drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f);
// Check the result, especially the boundaries. // Check the result, especially the boundaries.
EXPECT_PIXEL_COLOR_EQ(64, 0, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(127, 32, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(127, 32, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(64, 32, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(64, 32, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(0, 63, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(0, 63, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(64, 63, GLColor::blue); EXPECT_PIXEL_COLOR_EQ(64, 63, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(127, 63, GLColor::blue);
// Some pixels around x=0 still fail on android.There are other issues to fix. // Some pixels around x=0/127 or y=0 (related to the pre-rotation degree)still fail on android.
// We need to fix blit with pre-rotation. http://anglebug.com/5044 // We need to fix blit with pre-rotation. http://anglebug.com/5044
// Failures of Rotated90Degrees.
// EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(127, 63, GLColor::blue);
// Failures of Rotated180Degrees.
// EXPECT_PIXEL_COLOR_EQ(64, 0, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
// Failures of Rotated270Degrees.
// EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue); // EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
// EXPECT_PIXEL_COLOR_EQ(0, 32, GLColor::blue); // EXPECT_PIXEL_COLOR_EQ(0, 32, GLColor::blue);
...@@ -1186,17 +1189,11 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithFlip) ...@@ -1186,17 +1189,11 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithFlip)
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
// Blit color buffer to default framebuffer with flip and prerotation. // Blit color buffer to default framebuffer with Y-flip/X-flip.
TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithFlip) TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorToDefault)
{ {
// http://anglebug.com/4453 // This test uses functionality that is only available on Android
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel()); ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
// Flaky on Linux SwANGLE http://anglebug.com/4453
ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());
// We need to fix blit with pre-rotation. http://anglebug.com/5044
ANGLE_SKIP_TEST_IF(IsAndroid());
// To aid in debugging, we want this window visible // To aid in debugging, we want this window visible
setWindowVisible(mOSWindow, true); setWindowVisible(mOSWindow, true);
...@@ -1207,11 +1204,6 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithFlip) ...@@ -1207,11 +1204,6 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithFlip)
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext); eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
mOSWindow->setOrientation(300, 400);
angle::Sleep(1000);
eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS();
constexpr int kSize = 128; constexpr int kSize = 128;
glViewport(0, 0, kSize, kSize); glViewport(0, 0, kSize, kSize);
...@@ -1230,20 +1222,199 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithFlip) ...@@ -1230,20 +1222,199 @@ TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithFlip)
ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(), ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
essl31_shaders::fs::RedGreenGradient()); essl31_shaders::fs::RedGreenGradient());
EGLint desiredWidth = 300;
EGLint desiredHeight = 400;
mOSWindow->resize(desiredWidth, desiredHeight);
mOSWindow->setOrientation(desiredWidth, desiredHeight);
angle::Sleep(1000);
eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true); drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
// Blit color buffer to default frambuffer without flip.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
// Check the result, especially the boundaries.
EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow
// Blit color buffer to default frambuffer with Y-flip. // Blit color buffer to default frambuffer with Y-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0); // Yellow
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0); // Red
// Blit color buffer to default frambuffer with X-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0); // Green
ASSERT_GL_NO_ERROR();
}
// Blit color buffer from default framebuffer with Y-flip/X-flip.
TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorFromDefault)
{
// This test uses functionality that is only available on Android
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
// To aid in debugging, we want this window visible
setWindowVisible(mOSWindow, true);
initializeDisplay();
initializeSurfaceWithRGBA8888Config();
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_EGL_SUCCESS();
constexpr int kSize = 128;
glViewport(0, 0, kSize, kSize);
GLRenderbuffer colorbuf;
glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);
GLFramebuffer framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
glCheckFramebufferStatus(GL_FRAMEBUFFER);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
essl31_shaders::fs::RedGreenGradient());
EGLint desiredWidth = 300;
EGLint desiredHeight = 400;
mOSWindow->resize(desiredWidth, desiredHeight);
mOSWindow->setOrientation(desiredWidth, desiredHeight);
angle::Sleep(1000);
eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
// Blit color buffer from default frambuffer without flip.
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
// Check the result, especially the boundaries. // Check the result, especially the boundaries.
EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow
// Blit color buffer from default frambuffer with Y-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0); // Green EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0); // Yellow EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0); // Yellow
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0); // Balck EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0); // Red EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0); // Red
// Blit color buffer from default frambuffer with X-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());
glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0); // Green
ASSERT_GL_NO_ERROR();
}
// Blit multisample color buffer to resolved framebuffer.
TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleColorToResolved)
{
// This test uses functionality that is only available on Android
ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());
// To aid in debugging, we want this window visible
setWindowVisible(mOSWindow, true);
initializeDisplay();
initializeSurfaceWithRGBA8888Config();
eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);
ASSERT_EGL_SUCCESS();
constexpr int kSize = 128;
glViewport(0, 0, kSize, kSize);
GLRenderbuffer colorMS;
glBindRenderbuffer(GL_RENDERBUFFER, colorMS.get());
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize, kSize);
GLRenderbuffer colorResolved;
glBindRenderbuffer(GL_RENDERBUFFER, colorResolved.get());
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
GLFramebuffer framebufferMS;
glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS.get());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
glCheckFramebufferStatus(GL_FRAMEBUFFER);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
essl31_shaders::fs::RedGreenGradient());
drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
GLFramebuffer framebufferResolved;
glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
colorResolved.get());
EGLint desiredWidth = 300;
EGLint desiredHeight = 400;
mOSWindow->resize(desiredWidth, desiredHeight);
mOSWindow->setOrientation(desiredWidth, desiredHeight);
angle::Sleep(1000);
eglSwapBuffers(mDisplay, mWindowSurface); eglSwapBuffers(mDisplay, mWindowSurface);
ASSERT_EGL_SUCCESS();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferMS.get());
drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS.get());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferResolved.get());
glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferResolved.get());
// Check the result, especially the boundaries.
EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck
EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red
EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green
EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
} }
......
...@@ -415,6 +415,90 @@ TEST_P(BlitFramebufferANGLETest, BlitColorToDefault) ...@@ -415,6 +415,90 @@ TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow); EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
} }
// Blit color to/from default framebuffer with Flip-X/Flip-Y.
TEST_P(BlitFramebufferANGLETest, BlitColorWithFlip)
{
// OpenGL ES 3.0 Required.
ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 ||
!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
EXPECT_GL_NO_ERROR();
// Blit to default with x-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
// Blit to default with y-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
// Blit from default with x-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
// Blit from default with y-flip.
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
}
// Draw to system framebuffer, blit whole-buffer color to user-created framebuffer. // Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
TEST_P(BlitFramebufferANGLETest, ReverseColorBlit) TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment