diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/ViewportTest.cpp')
-rwxr-xr-x | gfx/angle/src/tests/gl_tests/ViewportTest.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/ViewportTest.cpp b/gfx/angle/src/tests/gl_tests/ViewportTest.cpp new file mode 100755 index 000000000..8cd9cd3df --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/ViewportTest.cpp @@ -0,0 +1,272 @@ +// +// Copyright 2015 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. +// + +#include "test_utils/ANGLETest.h" + +using namespace angle; + +namespace +{ + +class ViewportTest : public ANGLETest +{ + protected: + ViewportTest() + { + setWindowWidth(512); + setWindowHeight(512); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + setConfigDepthBits(24); + + mProgram = 0; + } + + void runNonScissoredTest() + { + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + runTest(); + } + + void runScissoredTest() + { + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glEnable(GL_SCISSOR_TEST); + glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2); + + runTest(); + } + + void runTest() + { + // Firstly ensure that no errors have been hit. + EXPECT_GL_NO_ERROR(); + + GLint viewportSize[4]; + glGetIntegerv(GL_VIEWPORT, viewportSize); + + // Clear to green. Might be a scissored clear, if scissorSize != window size + glClearColor(0, 1, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw a red quad centered in the middle of the viewport, with dimensions 25% of the size of the viewport. + drawQuad(mProgram, "position", 0.5f, 0.25f); + + GLint centerViewportX = viewportSize[0] + (viewportSize[2] / 2); + GLint centerViewportY = viewportSize[1] + (viewportSize[3] / 2); + + GLint redQuadLeftSideX = viewportSize[0] + viewportSize[2] * 3 / 8; + GLint redQuadRightSideX = viewportSize[0] + viewportSize[2] * 5 / 8; + GLint redQuadTopSideY = viewportSize[1] + viewportSize[3] * 3 / 8; + GLint redQuadBottomSideY = viewportSize[1] + viewportSize[3] * 5 / 8; + + // The midpoint of the viewport should be red. + checkPixel(centerViewportX, centerViewportY, true); + + // Pixels just inside the red quad should be red. + checkPixel(redQuadLeftSideX, redQuadTopSideY, true); + checkPixel(redQuadLeftSideX, redQuadBottomSideY - 1, true); + checkPixel(redQuadRightSideX - 1, redQuadTopSideY, true); + checkPixel(redQuadRightSideX - 1, redQuadBottomSideY - 1, true); + + // Pixels just outside the red quad shouldn't be red. + checkPixel(redQuadLeftSideX - 1, redQuadTopSideY - 1, false); + checkPixel(redQuadLeftSideX - 1, redQuadBottomSideY, false); + checkPixel(redQuadRightSideX, redQuadTopSideY - 1, false); + checkPixel(redQuadRightSideX, redQuadBottomSideY, false); + + // Pixels just within the viewport shouldn't be red. + checkPixel(viewportSize[0], viewportSize[1], false); + checkPixel(viewportSize[0], viewportSize[1] + viewportSize[3] - 1, false); + checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1], false); + checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1] + viewportSize[3] - 1, false); + } + + void checkPixel(GLint x, GLint y, GLboolean renderedRed) + { + // By default, expect the pixel to be black. + GLint expectedRedChannel = 0; + GLint expectedGreenChannel = 0; + + GLint scissorSize[4]; + glGetIntegerv(GL_SCISSOR_BOX, scissorSize); + + EXPECT_GL_NO_ERROR(); + + if (scissorSize[0] <= x && x < scissorSize[0] + scissorSize[2] + && scissorSize[1] <= y && y < scissorSize[1] + scissorSize[3]) + { + // If the pixel lies within the scissor rect, then it should have been cleared to green. + // If we rendered a red square on top of it, then the pixel should be red (the green channel will have been reset to 0). + expectedRedChannel = renderedRed ? 255 : 0; + expectedGreenChannel = renderedRed ? 0 : 255; + } + + // If the pixel is within the bounds of the window, then we check it. Otherwise we skip it. + if (0 <= x && x < getWindowWidth() && 0 <= y && y < getWindowHeight()) + { + EXPECT_PIXEL_EQ(x, y, expectedRedChannel, expectedGreenChannel, 0, 255); + } + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string testVertexShaderSource = SHADER_SOURCE + ( + attribute highp vec4 position; + + void main(void) + { + gl_Position = position; + } + ); + + const std::string testFragmentShaderSource = SHADER_SOURCE + ( + void main(void) + { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } + ); + + mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource); + if (mProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + glUseProgram(mProgram); + + glClearColor(0, 0, 0, 1); + glClearDepthf(0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Call glViewport and glScissor with default parameters. + glScissor(0, 0, getWindowWidth(), getWindowHeight()); + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + glDisable(GL_DEPTH_TEST); + } + + void TearDown() override + { + glDeleteProgram(mProgram); + + ANGLETest::TearDown(); + } + + GLuint mProgram; +}; + +TEST_P(ViewportTest, QuarterWindow) +{ + glViewport(0, 0, getWindowWidth() / 4, getWindowHeight() / 4); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, QuarterWindowCentered) +{ + glViewport(getWindowWidth() * 3 / 8, getWindowHeight() * 3 / 8, getWindowWidth() / 4, getWindowHeight() / 4); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, FullWindow) +{ + glViewport(0, 0, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, FullWindowOffCenter) +{ + glViewport(-getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindow) +{ + glViewport(0, 0, getWindowWidth() * 2, getWindowHeight() * 2); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindowCentered) +{ + glViewport(-getWindowWidth() / 2, -getWindowHeight() / 2, getWindowWidth() * 2, getWindowHeight() * 2); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, DoubleWindowOffCenter) +{ + glViewport(-getWindowWidth() * 3 / 4, getWindowHeight() * 3 / 4, getWindowWidth(), getWindowHeight()); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindow) +{ + glViewport(0, 0, getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindowCentered) +{ + glViewport(-getWindowWidth(), -getWindowHeight(), getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +TEST_P(ViewportTest, TripleWindowOffCenter) +{ + glViewport(-getWindowWidth() * 3 / 2, -getWindowHeight() * 3 / 2, getWindowWidth() * 3, getWindowHeight() * 3); + + runNonScissoredTest(); + + runScissoredTest(); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against. +// D3D11 Feature Level 9 and D3D9 emulate large and negative viewports in the vertex shader. We should test both of these as well as D3D11 Feature Level 10_0+. +ANGLE_INSTANTIATE_TEST(ViewportTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES2_D3D11_FL9_3(), + ES2_OPENGLES(), + ES3_OPENGLES()); + +} // namespace |