summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/ViewportTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/ViewportTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/ViewportTest.cpp272
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