Edit

kc3-lang/angle/src/tests/gl_tests/ViewportTest.cpp

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2017-09-18 13:32:29
    Hash : a20af6d7
    Message : Use C++11 raw string literals instead of SHADER_SOURCE macro This is better in many ways: 1. It doesn't confuse clang format 2. \n doesn't need to be included after preprocessor directives like the version directive. 3. It's using built-in functionality instead of something custom. Raw string literals should be the preferred way to include shader source in C++ files going forward. BUG=angleproject:2157 TEST=angle_end2end_tests Change-Id: I8b236a6e2d5c25d920297e5bc5b5b143eddeba1f Reviewed-on: https://chromium-review.googlesource.com/671046 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/tests/gl_tests/ViewportTest.cpp
  • //
    // 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 =
                R"(attribute highp vec4 position;
    
                void main(void)
                {
                    gl_Position = position;
                })";
    
            const std::string testFragmentShaderSource =
                R"(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