Edit

kc3-lang/angle/src/tests/egl_tests/EGLContextCompatibilityTest.cpp

Branch :

  • Show log

    Commit

  • Author : Frank Henigman
    Date : 2016-06-21 13:56:54
    Hash : c4aba275
    Message : Cast display for eglGetPlatformDisplayEXT(). Cast the second parameter of eglGetPlatformDisplayEXT() to the correct type to stop compiler complaining. BUG=angleproject:1297 Change-Id: I37260edbd0fb6b92c24b556b15ea8206295e12d4 Reviewed-on: https://chromium-review.googlesource.com/354740 Reviewed-by: Yuly Novikov <ynovikov@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Frank Henigman <fjhenigman@chromium.org>

  • src/tests/egl_tests/EGLContextCompatibilityTest.cpp
  • //
    // Copyright (c) 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.
    //
    
    // EGLContextCompatibilityTest.cpp:
    //   This test will try to use all combinations of context configs and
    //   surface configs. If the configs are compatible, it checks that simple
    //   rendering works, otherwise it checks an error is generated one MakeCurrent.
    #include <gtest/gtest.h>
    
    #include <vector>
    #include <EGL/egl.h>
    #include <EGL/eglext.h>
    
    #include "OSWindow.h"
    #include "test_utils/ANGLETest.h"
    #include "test_utils/angle_test_configs.h"
    
    using namespace angle;
    
    namespace
    {
    
    const EGLint contextAttribs[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };
    
    }
    
    class EGLContextCompatibilityTest : public ANGLETest
    {
      public:
        EGLContextCompatibilityTest()
          : mDisplay(0)
        {
        }
    
        void SetUp() override
        {
            PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
            ASSERT_TRUE(eglGetPlatformDisplayEXT != nullptr);
    
            EGLint dispattrs[] =
            {
                EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                EGL_NONE
            };
            mDisplay = eglGetPlatformDisplayEXT(
                EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
            ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
    
            ASSERT_TRUE(eglInitialize(mDisplay, nullptr, nullptr) == EGL_TRUE);
    
            int nConfigs = 0;
            ASSERT_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &nConfigs) == EGL_TRUE);
            ASSERT_TRUE(nConfigs != 0);
    
            int nReturnedConfigs = 0;
            mConfigs.resize(nConfigs);
            ASSERT_TRUE(eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs) == EGL_TRUE);
            ASSERT_TRUE(nConfigs == nReturnedConfigs);
        }
    
        void TearDown() override
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            eglTerminate(mDisplay);
        };
    
      protected:
        bool areConfigsCompatible(EGLConfig c1, EGLConfig c2, EGLint surfaceBit)
        {
            EGLint colorBufferType1, colorBufferType2;
            EGLint red1, red2, green1, green2, blue1, blue2, alpha1, alpha2;
            EGLint depth1, depth2, stencil1, stencil2;
            EGLint surfaceType1, surfaceType2;
    
            eglGetConfigAttrib(mDisplay, c1, EGL_COLOR_BUFFER_TYPE, &colorBufferType1);
            eglGetConfigAttrib(mDisplay, c2, EGL_COLOR_BUFFER_TYPE, &colorBufferType2);
    
            eglGetConfigAttrib(mDisplay, c1, EGL_RED_SIZE, &red1);
            eglGetConfigAttrib(mDisplay, c2, EGL_RED_SIZE, &red2);
            eglGetConfigAttrib(mDisplay, c1, EGL_GREEN_SIZE, &green1);
            eglGetConfigAttrib(mDisplay, c2, EGL_GREEN_SIZE, &green2);
            eglGetConfigAttrib(mDisplay, c1, EGL_BLUE_SIZE, &blue1);
            eglGetConfigAttrib(mDisplay, c2, EGL_BLUE_SIZE, &blue2);
            eglGetConfigAttrib(mDisplay, c1, EGL_ALPHA_SIZE, &alpha1);
            eglGetConfigAttrib(mDisplay, c2, EGL_ALPHA_SIZE, &alpha2);
    
            eglGetConfigAttrib(mDisplay, c1, EGL_DEPTH_SIZE, &depth1);
            eglGetConfigAttrib(mDisplay, c2, EGL_DEPTH_SIZE, &depth2);
            eglGetConfigAttrib(mDisplay, c1, EGL_STENCIL_SIZE, &stencil1);
            eglGetConfigAttrib(mDisplay, c2, EGL_STENCIL_SIZE, &stencil2);
    
            eglGetConfigAttrib(mDisplay, c1, EGL_SURFACE_TYPE, &surfaceType1);
            eglGetConfigAttrib(mDisplay, c2, EGL_SURFACE_TYPE, &surfaceType2);
    
            return colorBufferType1 == colorBufferType2 &&
                   red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2 &&
                   depth1 == depth2 && stencil1 == stencil2 &&
                   (surfaceType1 & surfaceBit) != 0 &&
                   (surfaceType2 & surfaceBit) != 0;
        }
    
        void testWindowCompatibility(EGLConfig windowConfig, EGLConfig contextConfig, bool compatible) const
        {
            OSWindow *osWindow = CreateOSWindow();
            ASSERT_TRUE(osWindow != nullptr);
            osWindow->initialize("EGLContextCompatibilityTest", 500, 500);
            osWindow->setVisible(true);
    
            EGLContext context = eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, contextAttribs);
            ASSERT_TRUE(context != EGL_NO_CONTEXT);
    
            EGLSurface window = eglCreateWindowSurface(mDisplay, windowConfig, osWindow->getNativeWindow(), nullptr);
            ASSERT_EGL_SUCCESS();
    
            if (compatible)
            {
                testClearSurface(window, context);
            }
            else
            {
                testMakeCurrentFails(window, context);
            }
    
            eglDestroySurface(mDisplay, window);
            ASSERT_EGL_SUCCESS();
    
            eglDestroyContext(mDisplay, context);
            ASSERT_EGL_SUCCESS();
    
            SafeDelete(osWindow);
        }
    
        void testPbufferCompatibility(EGLConfig pbufferConfig, EGLConfig contextConfig, bool compatible) const
        {
            EGLContext context = eglCreateContext(mDisplay, contextConfig, EGL_NO_CONTEXT, contextAttribs);
            ASSERT_TRUE(context != EGL_NO_CONTEXT);
    
            const EGLint pBufferAttribs[] =
            {
                EGL_WIDTH, 500,
                EGL_HEIGHT, 500,
                EGL_NONE,
            };
            EGLSurface pbuffer = eglCreatePbufferSurface(mDisplay, pbufferConfig, pBufferAttribs);
            ASSERT_TRUE(pbuffer != EGL_NO_SURFACE);
    
            if (compatible)
            {
                testClearSurface(pbuffer, context);
            }
            else
            {
                testMakeCurrentFails(pbuffer, context);
            }
    
            eglDestroySurface(mDisplay, pbuffer);
            ASSERT_EGL_SUCCESS();
    
            eglDestroyContext(mDisplay, context);
            ASSERT_EGL_SUCCESS();
        }
    
        std::vector<EGLConfig> mConfigs;
        EGLDisplay mDisplay;
    
      private:
        void testClearSurface(EGLSurface surface, EGLContext context) const
        {
            eglMakeCurrent(mDisplay, surface, surface, context);
            ASSERT_EGL_SUCCESS();
    
            glViewport(0, 0, 500, 500);
            glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            ASSERT_GL_NO_ERROR();
            EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);
    
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            ASSERT_EGL_SUCCESS();
        }
    
        void testMakeCurrentFails(EGLSurface surface, EGLContext context) const
        {
            eglMakeCurrent(mDisplay, surface, surface, context);
            EXPECT_EGL_ERROR(EGL_BAD_MATCH);
        }
    };
    
    // The test is split in several subtest so that simple cases
    // are tested separately. Also each surface types are not tested
    // together.
    
    // Basic test checking contexts and windows created with the
    // same config can render.
    TEST_P(EGLContextCompatibilityTest, WindowSameConfig)
    {
        for (size_t i = 0; i < mConfigs.size(); i++)
        {
            EGLConfig config = mConfigs[i];
    
            EGLint surfaceType;
            eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
            ASSERT_EGL_SUCCESS();
    
            if ((surfaceType & EGL_WINDOW_BIT) != 0)
            {
                testWindowCompatibility(config, config, true);
            }
        }
    }
    
    // Basic test checking contexts and pbuffers created with the
    // same config can render.
    TEST_P(EGLContextCompatibilityTest, PbufferSameConfig)
    {
        for (size_t i = 0; i < mConfigs.size(); i++)
        {
            EGLConfig config = mConfigs[i];
    
            EGLint surfaceType;
            eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType);
            ASSERT_EGL_SUCCESS();
    
            if ((surfaceType & EGL_PBUFFER_BIT) != 0)
            {
                testPbufferCompatibility(config, config, true);
            }
        }
    }
    
    // Check that a context rendering to a window with a different
    // config works or errors according to the EGL compatibility rules
    TEST_P(EGLContextCompatibilityTest, WindowDifferentConfig)
    {
        for (size_t i = 0; i < mConfigs.size(); i++)
        {
            EGLConfig config1 = mConfigs[i];
            EGLint surfaceType;
            eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
            ASSERT_EGL_SUCCESS();
    
            if ((surfaceType & EGL_WINDOW_BIT) == 0)
            {
                continue;
            }
    
            for (size_t j = 0; j < mConfigs.size(); j++)
            {
                EGLConfig config2 = mConfigs[j];
                testWindowCompatibility(config1, config2,
                                        areConfigsCompatible(config1, config2, EGL_WINDOW_BIT));
            }
        }
    }
    
    // Check that a context rendering to a pbuffer with a different
    // config works or errors according to the EGL compatibility rules
    TEST_P(EGLContextCompatibilityTest, PbufferDifferentConfig)
    {
        for (size_t i = 0; i < mConfigs.size(); i++)
        {
            EGLConfig config1 = mConfigs[i];
            EGLint surfaceType;
            eglGetConfigAttrib(mDisplay, config1, EGL_SURFACE_TYPE, &surfaceType);
            ASSERT_EGL_SUCCESS();
    
            if ((surfaceType & EGL_PBUFFER_BIT) == 0)
            {
                continue;
            }
    
            for (size_t j = 0; j < mConfigs.size(); j++)
            {
                EGLConfig config2 = mConfigs[j];
                testPbufferCompatibility(config1, config2, areConfigsCompatible(config1, config2, EGL_PBUFFER_BIT));
            }
        }
    }
    
    ANGLE_INSTANTIATE_TEST(EGLContextCompatibilityTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL());