Path: blob/main_old/src/tests/egl_tests/EGLSyncControlTest.cpp
1693 views
//1// Copyright 2016 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// EGLSyncControlTest.cpp:7// Tests pertaining to eglGetSyncValuesCHROMIUM.89#include <d3d11.h>1011#include "test_utils/ANGLETest.h"12#include "util/OSWindow.h"13#include "util/com_utils.h"1415using namespace angle;1617class EGLSyncControlTest : public testing::Test18{19protected:20EGLSyncControlTest() {}2122void SetUp() override23{24mD3D11Module = LoadLibrary(TEXT("d3d11.dll"));25if (mD3D11Module == nullptr)26{27std::cout << "Unable to LoadLibrary D3D11" << std::endl;28return;29}3031mD3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(32GetProcAddress(mD3D11Module, "D3D11CreateDevice"));33if (mD3D11CreateDevice == nullptr)34{35std::cout << "Could not retrieve D3D11CreateDevice from d3d11.dll" << std::endl;36return;37}3839mD3D11Available = true;4041const char *extensionString =42static_cast<const char *>(eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS));43if (strstr(extensionString, "EGL_ANGLE_device_creation"))44{45if (strstr(extensionString, "EGL_ANGLE_device_creation_d3d11"))46{47mDeviceCreationD3D11ExtAvailable = true;48}49}50}5152void TearDown() override53{54SafeRelease(mDevice);55SafeRelease(mDeviceContext);5657OSWindow::Delete(&mOSWindow);5859if (mSurface != EGL_NO_SURFACE)60{61eglDestroySurface(mDisplay, mSurface);62mSurface = EGL_NO_SURFACE;63}6465if (mContext != EGL_NO_CONTEXT)66{67eglDestroyContext(mDisplay, mContext);68mContext = EGL_NO_CONTEXT;69}7071if (mDisplay != EGL_NO_DISPLAY)72{73eglTerminate(mDisplay);74mDisplay = EGL_NO_DISPLAY;75}76}7778void CreateD3D11Device()79{80ASSERT_TRUE(mD3D11Available);81ASSERT_EQ(nullptr, mDevice); // The device shouldn't be created twice8283HRESULT hr =84mD3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, 0, nullptr, 0,85D3D11_SDK_VERSION, &mDevice, &mFeatureLevel, &mDeviceContext);8687ASSERT_TRUE(SUCCEEDED(hr));88}8990void InitializeDisplay()91{92EGLint displayAttribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,93EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,94EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE,95EGL_DONT_CARE,96EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE,97EGL_DONT_CARE,98EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,99EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,100EGL_NONE};101102// Create an OS Window103mOSWindow = OSWindow::New();104mOSWindow->initialize("EGLSyncControlTest", 64, 64);105mOSWindow->setVisible(true);106107// Create an EGLDisplay using the EGLDevice108mDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,109reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),110displayAttribs);111ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);112113EGLint majorVersion, minorVersion;114ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);115}116117void CreateWindowSurface()118{119eglBindAPI(EGL_OPENGL_ES_API);120ASSERT_EGL_SUCCESS();121122// Choose a config123const EGLint configAttributes[] = {EGL_NONE};124125EGLint configCount = 0;126ASSERT_EGL_TRUE(eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount));127128const EGLint surfaceAttributes[] = {EGL_DIRECT_COMPOSITION_ANGLE, EGL_TRUE, EGL_NONE};129130// Create window surface131mSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),132surfaceAttributes);133if (mSurface == nullptr)134{135std::cout << "Unable to create window surface with Direct Composition" << std::endl;136return;137}138139mDirectCompositionSurfaceAvailable = true;140141// Create EGL context142EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};143144mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);145ASSERT_EGL_SUCCESS();146147// Make the surface current148eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);149ASSERT_EGL_SUCCESS();150}151152bool mD3D11Available = false;153HMODULE mD3D11Module = nullptr;154PFN_D3D11_CREATE_DEVICE mD3D11CreateDevice = nullptr;155156ID3D11Device *mDevice = nullptr;157ID3D11DeviceContext *mDeviceContext = nullptr;158D3D_FEATURE_LEVEL mFeatureLevel;159160bool mDeviceCreationD3D11ExtAvailable = false;161162bool mDirectCompositionSurfaceAvailable = false;163164OSWindow *mOSWindow = nullptr;165166EGLDisplay mDisplay = EGL_NO_DISPLAY;167EGLSurface mSurface = EGL_NO_SURFACE;168EGLContext mContext = EGL_NO_CONTEXT;169EGLConfig mConfig = 0;170};171172// Basic test for eglGetSyncValuesCHROMIUM extension. Verifies that eglGetSyncValuesCHROMIUM173// can be called on DX11 with direct composition and that it returns reasonable enough values.174TEST_F(EGLSyncControlTest, DISABLED_SyncValuesTest)175{176static const DWORD kPollInterval = 10;177static const int kNumPollIterations = 100;178179if (!mD3D11Available)180{181std::cout << "D3D11 not available, skipping test" << std::endl;182return;183}184185CreateD3D11Device();186InitializeDisplay();187CreateWindowSurface();188189if (!mDirectCompositionSurfaceAvailable)190{191std::cout << "Direct Composition surface not available, skipping test" << std::endl;192return;193}194195const char *extensionString =196static_cast<const char *>(eglQueryString(mDisplay, EGL_EXTENSIONS));197ASSERT_TRUE(strstr(extensionString, "EGL_CHROMIUM_sync_control"));198199EGLuint64KHR ust = 0, msc = 0, sbc = 0;200// It appears there is a race condition so the very first call to eglGetSyncValuesCHROMIUM201// can fail within D3D with DXGI_ERROR_FRAME_STATISTICS_DISJOINT.202// Should that be handled inside eglGetSyncValuesCHROMIUM?203eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc);204205ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));206// Initial msc and sbc value should be true. Initial ust value is unspecified.207ASSERT_EQ(0ull, msc);208ASSERT_EQ(0ull, sbc);209210// Perform some very basic rendering.211glClearColor(1.0f, 0.0f, 1.0f, 1.0f);212glClear(GL_COLOR_BUFFER_BIT);213ASSERT_GL_NO_ERROR();214215ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));216217// Poll until sbc value increases. Normally it should change within 16-17 ms.218for (int i = 0; i < kNumPollIterations; i++)219{220::Sleep(kPollInterval);221ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust, &msc, &sbc));222if (sbc > 0)223break;224}225226// sbc should change to 1. msc and ust to some non-zero values.227ASSERT_EQ(1ull, sbc);228ASSERT_GT(ust, 0ull);229ASSERT_GT(msc, 0ull);230231// Perform more rendering.232glClearColor(0.0f, 0.0f, 1.0f, 1.0f);233glClear(GL_COLOR_BUFFER_BIT);234ASSERT_GL_NO_ERROR();235236ASSERT_EGL_TRUE(eglSwapBuffers(mDisplay, mSurface));237238// Poll until sbc value increases. Normally it should change within 16-17 ms.239EGLuint64KHR ust2 = 0, msc2 = 0, sbc2 = 0;240for (int i = 0; i < kNumPollIterations; i++)241{242::Sleep(kPollInterval);243ASSERT_EGL_TRUE(eglGetSyncValuesCHROMIUM(mDisplay, mSurface, &ust2, &msc2, &sbc2));244if (sbc2 > sbc)245break;246}247248// sbc2 should be 2. msc2 and ust2 should be greater than previous msc and ust values.249ASSERT_EQ(2ull, sbc2);250ASSERT_GT(ust2, ust);251ASSERT_GT(msc2, msc);252}253254255