Edit

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

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2019-08-15 09:02:43
    Hash : 188b679b
    Message : Remove GL/EGL function pointers from tests. The auto-gen loader code should be able to handle all these cases. Bug: angleproject:3393 Change-Id: If0a90fb29d79f2892fdf76fe0cb91ed0036ee1e3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1756083 Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>

  • src/tests/egl_tests/EGLSyncControlTest.cpp
  • //
    // Copyright 2016 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.
    //
    
    // EGLSyncControlTest.cpp:
    //   Tests pertaining to eglGetSyncValuesCHROMIUM.
    
    #include <d3d11.h>
    
    #include "test_utils/ANGLETest.h"
    #include "util/OSWindow.h"
    #include "util/com_utils.h"
    
    using namespace angle;
    
    class EGLSyncControlTest : public testing::Test
    {
      protected:
        EGLSyncControlTest() {}
    
        void SetUp() override
        {
            mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));
            if (mD3D11Module == nullptr)
            {
                std::cout << "Unable to LoadLibrary D3D11" << std::endl;
                return;
            }
    
            mD3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
                GetProcAddress(mD3D11Module, "D3D11CreateDevice"));
            if (mD3D11CreateDevice == nullptr)
            {
                std::cout << "Could not retrieve D3D11CreateDevice from d3d11.dll" << std::endl;
                return;
            }
    
            mD3D11Available = true;
    
            const char *extensionString =
                static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));
            if (strstr(extensionString, "EGL_ANGLE_device_creation"))
            {
                if (strstr(extensionString, "EGL_ANGLE_device_creation_d3d11"))
                {
                    mDeviceCreationD3D11ExtAvailable = true;
                }
            }
        }
    
        void TearDown() override
        {
            SafeRelease(mDevice);
            SafeRelease(mDeviceContext);
    
            OSWindow::Delete(&mOSWindow);
    
            if (mSurface != EGL_NO_SURFACE)
            {
                eglDestroySurface(mDisplay, mSurface);
                mSurface = EGL_NO_SURFACE;
            }
    
            if (mContext != EGL_NO_CONTEXT)
            {
                eglDestroyContext(mDisplay, mContext);
                mContext = EGL_NO_CONTEXT;
            }
    
            if (mDisplay != EGL_NO_DISPLAY)
            {
                eglTerminate(mDisplay);
                mDisplay = EGL_NO_DISPLAY;
            }
        }
    
        void CreateD3D11Device()
        {
            ASSERT_TRUE(mD3D11Available);
            ASSERT_EQ(nullptr, mDevice);  // The device shouldn't be created twice
    
            HRESULT hr =
                mD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, nullptr, 0,
                                   D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, &mDeviceContext);
    
            ASSERT_TRUE(SUCCEEDED(hr));
        }
    
        void InitializeDisplay()
        {
            EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                                       EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
                                       EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,
                                       EGL_DONT_CARE,
                                       EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,
                                       EGL_DONT_CARE,
                                       EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
                                       EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
                                       EGL_NONE};
    
            // Create an OS Window
            mOSWindow = OSWindow::New();
            mOSWindow->initialize("EGLSyncControlTest", 64, 64);
            mOSWindow->setVisible(true);
    
            // Create an EGLDisplay using the EGLDevice
            mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
                                                reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),
                                                displayAttribs);
            ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);
    
            EGLint majorVersion, minorVersion;
            ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);
        }
    
        void CreateWindowSurface()
        {
            eglBindAPI(EGL_OPENGL_ES_API);
            ASSERT_EGL_SUCCESS();
    
            // Choose a config
            const EGLint configAttributes[] = {EGL_NONE};
    
            EGLint configCount = 0;
            ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount));
    
            const EGLint surfaceAttributes[] = {EGL_DIRECT_COMPOSITION_ANGLE, EGL_TRUE, EGL_NONE};
    
            // Create window surface
            mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),
                                              surfaceAttributes);
            if (mSurface == nullptr)
            {
                std::cout << "Unable to create window surface with Direct Composition" << std::endl;
                return;
            }
    
            mDirectCompositionSurfaceAvailable = true;
    
            // Create EGL context
            EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    
            mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);
            ASSERT_EGL_SUCCESS();
    
            // Make the surface current
            eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
            ASSERT_EGL_SUCCESS();
        }
    
        bool mD3D11Available                       = false;
        HMODULE mD3D11Module                       = nullptr;
        PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice = nullptr;
    
        ID3D11Device *mDevice               = nullptr;
        ID3D11DeviceContext *mDeviceContext = nullptr;
        D3D_FEATURE_LEVEL mFeatureLevel;
    
        bool mDeviceCreationD3D11ExtAvailable = false;
    
        bool mDirectCompositionSurfaceAvailable = false;
    
        OSWindow *mOSWindow = nullptr;
    
        EGLDisplay mDisplay = EGL_NO_DISPLAY;
        EGLSurface mSurface = EGL_NO_SURFACE;
        EGLContext mContext = EGL_NO_CONTEXT;
        EGLConfig mConfig   = 0;
    };
    
    // Basic test for eglGetSyncValuesCHROMIUM extension. Verifies that eglGetSyncValuesCHROMIUM
    // can be called on DX11 with direct composition and that it returns reasonable enough values.
    TEST_F(EGLSyncControlTest, DISABLED_SyncValuesTest)
    {
        static const DWORD kPollInterval    = 10;
        static const int kNumPollIterations = 100;
    
        if (!mD3D11Available)
        {
            std::cout << "D3D11 not available, skipping test" << std::endl;
            return;
        }
    
        CreateD3D11Device();
        InitializeDisplay();
        CreateWindowSurface();
    
        if (!mDirectCompositionSurfaceAvailable)
        {
            std::cout << "Direct Composition surface not available, skipping test" << std::endl;
            return;
        }
    
        const char *extensionString =
            static_cast<const char *>(eglQueryString(mDisplay, EGL_EXTENSIONS));
        ASSERT_TRUE(strstr(extensionString, "EGL_CHROMIUM_sync_control"));
    
        EGLuint64KHR ust = 0, msc = 0, sbc = 0;
        // It appears there is a race condition so the very first call to eglGetSyncValuesCHROMIUM
        // can fail within D3D with DXGI_ERROR_FRAME_STATISTICS_DISJOINT.
        // Should that be handled inside eglGetSyncValuesCHROMIUM?
        eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc);
    
        ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));
        // Initial msc and sbc value should be true. Initial ust value is unspecified.
        ASSERT_EQ(0ull, msc);
        ASSERT_EQ(0ull, sbc);
    
        // Perform some very basic rendering.
        glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();
    
        ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));
    
        // Poll until sbc value increases. Normally it should change within 16-17 ms.
        for (int i = 0; i < kNumPollIterations; i++)
        {
            ::Sleep(kPollInterval);
            ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));
            if (sbc > 0)
                break;
        }
    
        // sbc should change to 1. msc and ust to some non-zero values.
        ASSERT_EQ(1ull, sbc);
        ASSERT_GT(ust, 0ull);
        ASSERT_GT(msc, 0ull);
    
        // Perform more rendering.
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();
    
        ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));
    
        // Poll until sbc value increases. Normally it should change within 16-17 ms.
        EGLuint64KHR ust2 = 0, msc2 = 0, sbc2 = 0;
        for (int i = 0; i < kNumPollIterations; i++)
        {
            ::Sleep(kPollInterval);
            ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust2, &msc2, &sbc2));
            if (sbc2 > sbc)
                break;
        }
    
        // sbc2 should be 2. msc2 and ust2 should be greater than previous msc and ust values.
        ASSERT_EQ(2ull, sbc2);
        ASSERT_GT(ust2, ust);
        ASSERT_GT(msc2, msc);
    }