Edit

kc3-lang/angle/src/tests/test_utils/ANGLETest.cpp

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2016-01-11 17:12:57
    Hash : 4a8329f2
    Message : Refactoring: Split TextureTest to multiple classes This removes the cube map setup and the draw scale parameter from the tests that don't need them, and reuses the code for setting up the window and the shader program for most of the texture tests. The tests are now structured as follows: TexCoordDrawTest: Test class that sets up a shader program for drawing with texture coordinates. Vertex shader source can be overridden in subclasses, and fragment shader source must be specified in subclasses. Texture2DTest: Inherits TexCoordDrawTest, sets up a 2D texture and a shader for drawing from it. Texture2DTestWithDrawScale: Inherits Texture2DTest, adding a scale parameter that scales the quad that gets drawn. TextureCubeTest: Inherits TexCoordDrawTest, sets up a cube map and a 2D texture and a shader for drawing from them. Texture2DArrayTestES3: Inherits TexCoordDrawTest. Reserves a texture ID and sets up an ESSL3 shader for drawing from a 2D texture array. Also add a few comments about where things being tested are specified. Also, ANGLETest::drawQuad parameter names are renamed to make their meaning clearer. The parameters affect the vertex shader attribute values, which the shader may use for other things besides setting the vertex position. BUG=angleproject:1261 TEST=angle_end2end_tests Change-Id: Id673e36d5883aaaf47f2f830c2a1ad0ca293d578 Reviewed-on: https://chromium-review.googlesource.com/321620 Reviewed-by: Zhenyao Mo <zmo@chromium.org> Tested-by: Olli Etuaho <oetuaho@nvidia.com>

  • src/tests/test_utils/ANGLETest.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.
    //
    // ANGLETest:
    //   Implementation of common ANGLE testing fixture.
    //
    
    #include "ANGLETest.h"
    #include "EGLWindow.h"
    #include "OSWindow.h"
    #include "system_utils.h"
    
    ANGLETest::ANGLETest()
        : mEGLWindow(nullptr),
          mWidth(16),
          mHeight(16)
    {
        mEGLWindow =
            new EGLWindow(GetParam().majorVersion, GetParam().minorVersion, GetParam().eglParameters);
    }
    
    ANGLETest::~ANGLETest()
    {
        SafeDelete(mEGLWindow);
    }
    
    void ANGLETest::SetUp()
    {
        // Resize the window before creating the context so that the first make current
        // sets the viewport and scissor box to the right size.
        bool needSwap = false;
        if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight)
        {
            if (!mOSWindow->resize(mWidth, mHeight))
            {
                FAIL() << "Failed to resize ANGLE test window.";
            }
            needSwap = true;
        }
    
        if (!createEGLContext())
        {
            FAIL() << "egl context creation failed.";
        }
    
        if (needSwap)
        {
            // Swap the buffers so that the default framebuffer picks up the resize
            // which will allow follow-up test code to assume the framebuffer covers
            // the whole window.
            swapBuffers();
        }
    
        // This Viewport command is not strictly necessary but we add it so that programs
        // taking OpenGL traces can guess the size of the default framebuffer and show it
        // in their UIs
        glViewport(0, 0, mWidth, mHeight);
    
        const auto &info = testing::UnitTest::GetInstance()->current_test_info();
        angle::WriteDebugMessage("Entering %s.%s\n", info->test_case_name(), info->name());
    }
    
    void ANGLETest::TearDown()
    {
        const auto &info = testing::UnitTest::GetInstance()->current_test_info();
        angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
    
        swapBuffers();
        mOSWindow->messageLoop();
    
        if (!destroyEGLContext())
        {
            FAIL() << "egl context destruction failed.";
        }
    
        // Check for quit message
        Event myEvent;
        while (mOSWindow->popEvent(&myEvent))
        {
            if (myEvent.Type == Event::EVENT_CLOSED)
            {
                exit(0);
            }
        }
    }
    
    void ANGLETest::swapBuffers()
    {
        if (mEGLWindow->isGLInitialized())
        {
            mEGLWindow->swap();
        }
    }
    
    void ANGLETest::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ)
    {
        drawQuad(program, positionAttribName, positionAttribZ, 1.0f);
    }
    
    void ANGLETest::drawQuad(GLuint program,
                             const std::string &positionAttribName,
                             GLfloat positionAttribZ,
                             GLfloat positionAttribXYScale)
    {
        GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
    
        glUseProgram(program);
    
        const GLfloat vertices[] = {
            -1.0f * positionAttribXYScale,  1.0f * positionAttribXYScale, positionAttribZ,
            -1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
             1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
    
            -1.0f * positionAttribXYScale,  1.0f * positionAttribXYScale, positionAttribZ,
             1.0f * positionAttribXYScale, -1.0f * positionAttribXYScale, positionAttribZ,
             1.0f * positionAttribXYScale,  1.0f * positionAttribXYScale, positionAttribZ,
        };
    
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(positionLocation);
    
        glDrawArrays(GL_TRIANGLES, 0, 6);
    
        glDisableVertexAttribArray(positionLocation);
        glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    
        glUseProgram(0);
    }
    
    GLuint ANGLETest::compileShader(GLenum type, const std::string &source)
    {
        GLuint shader = glCreateShader(type);
    
        const char *sourceArray[1] = { source.c_str() };
        glShaderSource(shader, 1, sourceArray, NULL);
        glCompileShader(shader);
    
        GLint compileResult;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
    
        if (compileResult == 0)
        {
            GLint infoLogLength;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
    
            if (infoLogLength == 0)
            {
                std::cerr << "shader compilation failed with empty log." << std::endl;
            }
            else
            {
                std::vector<GLchar> infoLog(infoLogLength);
                glGetShaderInfoLog(shader, static_cast<GLsizei>(infoLog.size()), NULL, &infoLog[0]);
    
                std::cerr << "shader compilation failed: " << &infoLog[0];
            }
    
            glDeleteShader(shader);
            shader = 0;
        }
    
        return shader;
    }
    
    static bool checkExtensionExists(const char *allExtensions, const std::string &extName)
    {
        return strstr(allExtensions, extName.c_str()) != nullptr;
    }
    
    bool ANGLETest::extensionEnabled(const std::string &extName)
    {
        return checkExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
                                    extName);
    }
    
    bool ANGLETest::eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName)
    {
        return checkExtensionExists(eglQueryString(display, EGL_EXTENSIONS), extName);
    }
    
    bool ANGLETest::eglClientExtensionEnabled(const std::string &extName)
    {
        return checkExtensionExists(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS), extName);
    }
    
    void ANGLETest::setWindowWidth(int width)
    {
        mWidth = width;
    }
    
    void ANGLETest::setWindowHeight(int height)
    {
        mHeight = height;
    }
    
    void ANGLETest::setConfigRedBits(int bits)
    {
        mEGLWindow->setConfigRedBits(bits);
    }
    
    void ANGLETest::setConfigGreenBits(int bits)
    {
        mEGLWindow->setConfigGreenBits(bits);
    }
    
    void ANGLETest::setConfigBlueBits(int bits)
    {
        mEGLWindow->setConfigBlueBits(bits);
    }
    
    void ANGLETest::setConfigAlphaBits(int bits)
    {
        mEGLWindow->setConfigAlphaBits(bits);
    }
    
    void ANGLETest::setConfigDepthBits(int bits)
    {
        mEGLWindow->setConfigDepthBits(bits);
    }
    
    void ANGLETest::setConfigStencilBits(int bits)
    {
        mEGLWindow->setConfigStencilBits(bits);
    }
    
    void ANGLETest::setMultisampleEnabled(bool enabled)
    {
        mEGLWindow->setMultisample(enabled);
    }
    
    void ANGLETest::setDebugEnabled(bool enabled)
    {
        mEGLWindow->setDebugEnabled(enabled);
    }
    
    int ANGLETest::getClientVersion() const
    {
        return mEGLWindow->getClientMajorVersion();
    }
    
    EGLWindow *ANGLETest::getEGLWindow() const
    {
        return mEGLWindow;
    }
    
    int ANGLETest::getWindowWidth() const
    {
        return mWidth;
    }
    
    int ANGLETest::getWindowHeight() const
    {
        return mHeight;
    }
    
    bool ANGLETest::isMultisampleEnabled() const
    {
        return mEGLWindow->isMultisample();
    }
    
    bool ANGLETest::createEGLContext()
    {
        return mEGLWindow->initializeGL(mOSWindow);
    }
    
    bool ANGLETest::destroyEGLContext()
    {
        mEGLWindow->destroyGL();
        return true;
    }
    
    bool ANGLETest::InitTestWindow()
    {
        mOSWindow = CreateOSWindow();
        if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
        {
            return false;
        }
    
        mOSWindow->setVisible(true);
    
        return true;
    }
    
    bool ANGLETest::DestroyTestWindow()
    {
        if (mOSWindow)
        {
            mOSWindow->destroy();
            delete mOSWindow;
            mOSWindow = NULL;
        }
    
        return true;
    }
    
    void ANGLETest::SetWindowVisible(bool isVisible)
    {
        mOSWindow->setVisible(isVisible);
    }
    
    bool ANGLETest::isIntel() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("Intel") != std::string::npos);
    }
    
    bool ANGLETest::isAMD() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("AMD") != std::string::npos) ||
               (rendererString.find("ATI") != std::string::npos);
    }
    
    bool ANGLETest::isNVidia() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("NVIDIA") != std::string::npos);
    }
    
    bool ANGLETest::isD3D11() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("Direct3D11 vs_5_0") != std::string::npos);
    }
    
    bool ANGLETest::isD3D11_FL93() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("Direct3D11 vs_4_0_") != std::string::npos);
    }
    
    bool ANGLETest::isD3D9() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return (rendererString.find("Direct3D9") != std::string::npos);
    }
    
    bool ANGLETest::isD3DSM3() const
    {
        std::string rendererString(reinterpret_cast<const char *>(glGetString(GL_RENDERER)));
        return isD3D9() || isD3D11_FL93();
    }
    
    EGLint ANGLETest::getPlatformRenderer() const
    {
        assert(mEGLWindow);
        return mEGLWindow->getPlatform().renderer;
    }
    
    OSWindow *ANGLETest::mOSWindow = NULL;
    
    void ANGLETestEnvironment::SetUp()
    {
        if (!ANGLETest::InitTestWindow())
        {
            FAIL() << "Failed to create ANGLE test window.";
        }
    }
    
    void ANGLETestEnvironment::TearDown()
    {
        ANGLETest::DestroyTestWindow();
    }