From 0f566fc77c3d47adc39822f74cda4523c3a954b9 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Wed, 20 Mar 2019 11:36:29 -0400 Subject: [PATCH] Introduce ConfigParameters test helper struct. This allows us to more easily compare sets of parameters used in our tests. The config parameters are stuff like the red / gree / blue bits used in an EGL config. Or particular sets of extensions or other EGL options. This will more easily allow us to determine when we need to use a new EGL display instead of reusing a prior. Bug: angleproject:3261 Change-Id: Ia1f0ede988e0b4084fbb4d55097e94fd89ee4899 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1531535 Commit-Queue: Jamie Madill Reviewed-by: Yuly Novikov --- samples/sample_util/SampleApplication.cpp | 23 +- src/tests/gl_tests/ProgramBinaryTest.cpp | 3 +- src/tests/perf_tests/ANGLEPerfTest.cpp | 12 +- src/tests/perf_tests/ANGLEPerfTest.h | 1 + src/tests/test_utils/ANGLETest.cpp | 64 ++--- src/tests/test_utils/ANGLETest.h | 2 + .../test_utils/angle_test_instantiate.cpp | 6 +- util/EGLWindow.cpp | 232 +++++++++++------- util/EGLWindow.h | 156 ++++++------ util/windows/WGLWindow.cpp | 11 +- util/windows/WGLWindow.h | 4 +- 11 files changed, 300 insertions(+), 214 deletions(-) diff --git a/samples/sample_util/SampleApplication.cpp b/samples/sample_util/SampleApplication.cpp index 68c1db260..507e5d73e 100644 --- a/samples/sample_util/SampleApplication.cpp +++ b/samples/sample_util/SampleApplication.cpp @@ -70,16 +70,6 @@ SampleApplication::SampleApplication(std::string name, EGLPlatformParameters(requestedRenderer)); mTimer.reset(CreateTimer()); mOSWindow = OSWindow::New(); - - mEGLWindow->setConfigRedBits(8); - mEGLWindow->setConfigGreenBits(8); - mEGLWindow->setConfigBlueBits(8); - mEGLWindow->setConfigAlphaBits(8); - mEGLWindow->setConfigDepthBits(24); - mEGLWindow->setConfigStencilBits(8); - - // Disable vsync - mEGLWindow->setSwapInterval(0); } SampleApplication::~SampleApplication() @@ -138,7 +128,18 @@ int SampleApplication::run() mOSWindow->setVisible(true); - if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get())) + ConfigParameters configParams; + configParams.redBits = 8; + configParams.greenBits = 8; + configParams.blueBits = 8; + configParams.alphaBits = 8; + configParams.depthBits = 24; + configParams.stencilBits = 8; + + // Disable vsync + configParams.swapInterval = 0; + + if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), configParams)) { return -1; } diff --git a/src/tests/gl_tests/ProgramBinaryTest.cpp b/src/tests/gl_tests/ProgramBinaryTest.cpp index b4aae571e..0a94814b1 100644 --- a/src/tests/gl_tests/ProgramBinaryTest.cpp +++ b/src/tests/gl_tests/ProgramBinaryTest.cpp @@ -710,7 +710,8 @@ class ProgramBinariesAcrossPlatforms : public testing::TestWithParaminitializeGL(mOSWindow, mEntryPointsLib.get()); + ConfigParameters configParams; + bool result = eglWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), configParams); if (result == false) { EGLWindow::Delete(&eglWindow); diff --git a/src/tests/perf_tests/ANGLEPerfTest.cpp b/src/tests/perf_tests/ANGLEPerfTest.cpp index 0207cec80..1f5c2d8d7 100644 --- a/src/tests/perf_tests/ANGLEPerfTest.cpp +++ b/src/tests/perf_tests/ANGLEPerfTest.cpp @@ -416,7 +416,8 @@ void ANGLERenderTest::SetUp() return; } - mGLWindow->setSwapInterval(0); + // Disable vsync. + mConfigParams.swapInterval = 0; mPlatformMethods.overrideWorkaroundsD3D = OverrideWorkaroundsD3D; mPlatformMethods.logError = EmptyPlatformMethod; @@ -427,7 +428,8 @@ void ANGLERenderTest::SetUp() mPlatformMethods.updateTraceEventDuration = UpdateTraceEventDuration; mPlatformMethods.monotonicallyIncreasingTime = MonotonicallyIncreasingTime; mPlatformMethods.context = this; - mGLWindow->setPlatformMethods(&mPlatformMethods); + + mConfigParams.platformMethods = &mPlatformMethods; if (!mOSWindow->initialize(mName, mTestParams.windowWidth, mTestParams.windowHeight)) { @@ -436,7 +438,7 @@ void ANGLERenderTest::SetUp() // FAIL returns. } - if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get())) + if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mConfigParams)) { mSkipTest = true; FAIL() << "Failed initializing GL Window"; @@ -588,12 +590,12 @@ bool ANGLERenderTest::areExtensionPrerequisitesFulfilled() const void ANGLERenderTest::setWebGLCompatibilityEnabled(bool webglCompatibility) { - mGLWindow->setWebGLCompatibilityEnabled(webglCompatibility); + mConfigParams.webGLCompatibility = webglCompatibility; } void ANGLERenderTest::setRobustResourceInit(bool enabled) { - mGLWindow->setRobustResourceInit(enabled); + mConfigParams.robustResourceInit = enabled; } std::vector &ANGLERenderTest::getTraceEventBuffer() diff --git a/src/tests/perf_tests/ANGLEPerfTest.h b/src/tests/perf_tests/ANGLEPerfTest.h index 7907ad3cc..55e017c7c 100644 --- a/src/tests/perf_tests/ANGLEPerfTest.h +++ b/src/tests/perf_tests/ANGLEPerfTest.h @@ -163,6 +163,7 @@ class ANGLERenderTest : public ANGLEPerfTest OSWindow *mOSWindow; std::vector mExtensionPrerequisites; angle::PlatformMethods mPlatformMethods; + ConfigParameters mConfigParams; GLuint mTimestampQuery; diff --git a/src/tests/test_utils/ANGLETest.cpp b/src/tests/test_utils/ANGLETest.cpp index d532fa5ec..41c35eee6 100644 --- a/src/tests/test_utils/ANGLETest.cpp +++ b/src/tests/test_utils/ANGLETest.cpp @@ -319,7 +319,7 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters ¶ms) EGLWindow::New(params.majorVersion, params.minorVersion, params.eglParameters); // Default debug layers to enabled in tests. - mEGLWindow->setDebugLayersEnabled(true); + mConfigParameters.debugLayersEnabled = true; // Workaround for NVIDIA not being able to share OpenGL and Vulkan contexts. // Workaround if any of the GPUs is Nvidia, since we can't detect current GPU. @@ -406,7 +406,8 @@ void ANGLETestBase::ANGLETestSetUp() if (mWGLWindow) { #if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER) - if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary())) + if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary(), + mConfigParameters)) { std::cerr << "WGL init failed.. trying again with new OSWindow." << std::endl; @@ -419,7 +420,8 @@ void ANGLETestBase::ANGLETestSetUp() FAIL() << "Failed to create ANGLE test window."; } - if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary())) + if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary(), + mConfigParameters)) { FAIL() << "WGL init failed."; } @@ -436,12 +438,18 @@ void ANGLETestBase::ANGLETestSetUp() mPlatformMethods.logWarning = angle::TestPlatform_logWarning; mPlatformMethods.logInfo = angle::TestPlatform_logInfo; mPlatformMethods.context = &mPlatformContext; - mEGLWindow->setPlatformMethods(&mPlatformMethods); + mConfigParameters.platformMethods = &mPlatformMethods; - if (!mEGLWindow->initializeDisplayAndSurface(mOSWindow, - ANGLETestEnvironment::GetEGLLibrary())) + if (!mEGLWindow->initializeDisplay(mOSWindow, ANGLETestEnvironment::GetEGLLibrary(), + mConfigParameters)) { - FAIL() << "egl display or surface init failed."; + FAIL() << "egl display init failed."; + } + + if (!mEGLWindow->initializeSurface(mOSWindow, ANGLETestEnvironment::GetEGLLibrary(), + mConfigParameters)) + { + FAIL() << "egl surface init failed."; } if (!mDeferContextInit && !mEGLWindow->initializeContext()) @@ -471,7 +479,7 @@ void ANGLETestBase::ANGLETestTearDown() { if (mEGLWindow) { - mEGLWindow->setPlatformMethods(nullptr); + mConfigParameters.platformMethods = nullptr; checkD3D11SDKLayersMessages(); } @@ -991,102 +999,102 @@ GLWindowBase *ANGLETestBase::getGLWindow() const void ANGLETestBase::setConfigRedBits(int bits) { - getGLWindow()->setConfigRedBits(bits); + mConfigParameters.redBits = bits; } void ANGLETestBase::setConfigGreenBits(int bits) { - getGLWindow()->setConfigGreenBits(bits); + mConfigParameters.greenBits = bits; } void ANGLETestBase::setConfigBlueBits(int bits) { - getGLWindow()->setConfigBlueBits(bits); + mConfigParameters.blueBits = bits; } void ANGLETestBase::setConfigAlphaBits(int bits) { - getGLWindow()->setConfigAlphaBits(bits); + mConfigParameters.alphaBits = bits; } void ANGLETestBase::setConfigDepthBits(int bits) { - getGLWindow()->setConfigDepthBits(bits); + mConfigParameters.depthBits = bits; } void ANGLETestBase::setConfigStencilBits(int bits) { - getGLWindow()->setConfigStencilBits(bits); + mConfigParameters.stencilBits = bits; } void ANGLETestBase::setConfigComponentType(EGLenum componentType) { - mEGLWindow->setConfigComponentType(componentType); + mConfigParameters.componentType = componentType; } void ANGLETestBase::setMultisampleEnabled(bool enabled) { - mEGLWindow->setMultisample(enabled); + mConfigParameters.multisample = enabled; } void ANGLETestBase::setSamples(EGLint samples) { - mEGLWindow->setSamples(samples); + mConfigParameters.samples = samples; } void ANGLETestBase::setDebugEnabled(bool enabled) { - mEGLWindow->setDebugEnabled(enabled); + mConfigParameters.debug = enabled; } void ANGLETestBase::setNoErrorEnabled(bool enabled) { - mEGLWindow->setNoErrorEnabled(enabled); + mConfigParameters.noError = enabled; } void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility) { - mEGLWindow->setWebGLCompatibilityEnabled(webglCompatibility); + mConfigParameters.webGLCompatibility = webglCompatibility; } void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled) { - mEGLWindow->setExtensionsEnabled(extensionsEnabled); + mConfigParameters.extensionsEnabled = extensionsEnabled; } void ANGLETestBase::setRobustAccess(bool enabled) { - mEGLWindow->setRobustAccess(enabled); + mConfigParameters.robustAccess = enabled; } void ANGLETestBase::setBindGeneratesResource(bool bindGeneratesResource) { - mEGLWindow->setBindGeneratesResource(bindGeneratesResource); + mConfigParameters.bindGeneratesResource = bindGeneratesResource; } void ANGLETestBase::setDebugLayersEnabled(bool enabled) { - mEGLWindow->setDebugLayersEnabled(enabled); + mConfigParameters.debugLayersEnabled = enabled; } void ANGLETestBase::setClientArraysEnabled(bool enabled) { - mEGLWindow->setClientArraysEnabled(enabled); + mConfigParameters.clientArraysEnabled = enabled; } void ANGLETestBase::setRobustResourceInit(bool enabled) { - mEGLWindow->setRobustResourceInit(enabled); + mConfigParameters.robustResourceInit = enabled; } void ANGLETestBase::setContextProgramCacheEnabled(bool enabled) { - mEGLWindow->setContextProgramCacheEnabled(enabled); + mConfigParameters.contextProgramCacheEnabled = enabled; } void ANGLETestBase::setContextVirtualization(bool enabled) { - mEGLWindow->setContextVirtualization(enabled); + mConfigParameters.contextVirtualization = enabled; } void ANGLETestBase::setDeferContextInit(bool enabled) diff --git a/src/tests/test_utils/ANGLETest.h b/src/tests/test_utils/ANGLETest.h index 9b8e68f65..e3ea71bfb 100644 --- a/src/tests/test_utils/ANGLETest.h +++ b/src/tests/test_utils/ANGLETest.h @@ -18,6 +18,7 @@ #include "common/angleutils.h" #include "common/vector_utils.h" #include "platform/Platform.h" +#include "util/EGLWindow.h" #include "util/shader_utils.h" #include "util/system_utils.h" #include "util/util_gl.h" @@ -411,6 +412,7 @@ class ANGLETestBase EGLWindow *mEGLWindow; WGLWindow *mWGLWindow; + ConfigParameters mConfigParameters; int mWidth; int mHeight; diff --git a/src/tests/test_utils/angle_test_instantiate.cpp b/src/tests/test_utils/angle_test_instantiate.cpp index 028275c66..b0e4d902f 100644 --- a/src/tests/test_utils/angle_test_instantiate.cpp +++ b/src/tests/test_utils/angle_test_instantiate.cpp @@ -38,7 +38,8 @@ bool IsANGLEConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow) EGLWindow *eglWindow = EGLWindow::New(param.majorVersion, param.minorVersion, param.eglParameters); - bool result = eglWindow->initializeGL(osWindow, eglLibrary.get()); + ConfigParameters configParams; + bool result = eglWindow->initializeGL(osWindow, eglLibrary.get(), configParams); eglWindow->destroyGL(); EGLWindow::Delete(&eglWindow); return result; @@ -50,7 +51,8 @@ bool IsWGLConfigSupported(const PlatformParameters ¶m, OSWindow *osWindow) std::unique_ptr openglLibrary(angle::OpenSharedLibrary("opengl32")); WGLWindow *wglWindow = WGLWindow::New(param.majorVersion, param.minorVersion); - bool result = wglWindow->initializeGL(osWindow, openglLibrary.get()); + ConfigParameters configParams; + bool result = wglWindow->initializeGL(osWindow, openglLibrary.get(), configParams); wglWindow->destroyGL(); WGLWindow::Delete(&wglWindow); return result; diff --git a/util/EGLWindow.cpp b/util/EGLWindow.cpp index 0c2ae4834..e066bfb87 100644 --- a/util/EGLWindow.cpp +++ b/util/EGLWindow.cpp @@ -87,18 +87,36 @@ bool operator==(const EGLPlatformParameters &a, const EGLPlatformParameters &b) (a.presentPath == b.presentPath); } +// ConfigParameters implementation. +ConfigParameters::ConfigParameters() + : platformMethods(nullptr), + redBits(-1), + greenBits(-1), + blueBits(-1), + alphaBits(-1), + depthBits(-1), + stencilBits(-1), + swapInterval(-1), + componentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT), + multisample(false), + debug(false), + noError(false), + bindGeneratesResource(true), + clientArraysEnabled(true), + robustAccess(false), + samples(-1) +{} + +ConfigParameters::~ConfigParameters() = default; + +void ConfigParameters::reset() +{ + *this = ConfigParameters(); +} + // GLWindowBase implementation. GLWindowBase::GLWindowBase(EGLint glesMajorVersion, EGLint glesMinorVersion) - : mClientMajorVersion(glesMajorVersion), - mClientMinorVersion(glesMinorVersion), - mRedBits(-1), - mGreenBits(-1), - mBlueBits(-1), - mAlphaBits(-1), - mDepthBits(-1), - mStencilBits(-1), - mSwapInterval(-1), - mPlatformMethods(nullptr) + : mClientMajorVersion(glesMajorVersion), mClientMinorVersion(glesMinorVersion) {} GLWindowBase::~GLWindowBase() = default; @@ -108,24 +126,13 @@ EGLWindow::EGLWindow(EGLint glesMajorVersion, EGLint glesMinorVersion, const EGLPlatformParameters &platform) : GLWindowBase(glesMajorVersion, glesMinorVersion), + mConfig(0), mDisplay(EGL_NO_DISPLAY), mSurface(EGL_NO_SURFACE), mContext(EGL_NO_CONTEXT), mEGLMajorVersion(0), mEGLMinorVersion(0), - mPlatform(platform), - mComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT), - mMultisample(false), - mDebug(false), - mNoError(false), - mExtensionsEnabled(), - mBindGeneratesResource(true), - mClientArraysEnabled(true), - mRobustAccess(false), - mSamples(-1), - mDebugLayersEnabled(), - mContextProgramCacheEnabled(), - mContextVirtualization() + mPlatform(platform) {} EGLWindow::~EGLWindow() @@ -158,15 +165,23 @@ EGLContext EGLWindow::getContext() const return mContext; } -bool EGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibrary) +bool EGLWindow::initializeGL(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) { - if (!initializeDisplayAndSurface(osWindow, glWindowingLibrary)) + if (!initializeDisplay(osWindow, glWindowingLibrary, params)) + return false; + if (!initializeSurface(osWindow, glWindowingLibrary, params)) return false; return initializeContext(); } -bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library *glWindowingLibrary) +bool EGLWindow::initializeDisplay(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) { + mConfigParams = params; + #if defined(ANGLE_USE_UTIL_LOADER) PFNEGLGETPROCADDRESSPROC getProcAddress; glWindowingLibrary->getAs("eglGetProcAddress", &getProcAddress); @@ -208,23 +223,26 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library * } // Set debug layer settings if requested. - if (mDebugLayersEnabled.valid()) + if (mConfigParams.debugLayersEnabled.valid()) { displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE); - displayAttributes.push_back(mDebugLayersEnabled.value() ? EGL_TRUE : EGL_FALSE); + displayAttributes.push_back(mConfigParams.debugLayersEnabled.value() ? EGL_TRUE + : EGL_FALSE); } - if (mContextVirtualization.valid()) + if (mConfigParams.contextVirtualization.valid()) { displayAttributes.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE); - displayAttributes.push_back(mContextVirtualization.value() ? EGL_TRUE : EGL_FALSE); + displayAttributes.push_back(mConfigParams.contextVirtualization.value() ? EGL_TRUE + : EGL_FALSE); } - if (mPlatformMethods) + if (mConfigParams.platformMethods) { - static_assert(sizeof(EGLAttrib) == sizeof(mPlatformMethods), "Unexpected pointer size"); + static_assert(sizeof(EGLAttrib) == sizeof(mConfigParams.platformMethods), + "Unexpected pointer size"); displayAttributes.push_back(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX); - displayAttributes.push_back(reinterpret_cast(mPlatformMethods)); + displayAttributes.push_back(reinterpret_cast(mConfigParams.platformMethods)); } displayAttributes.push_back(EGL_NONE); @@ -244,22 +262,38 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library * return false; } + return true; +} + +bool EGLWindow::initializeSurface(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) +{ + mConfigParams = params; const char *displayExtensions = eglQueryString(mDisplay, EGL_EXTENSIONS); std::vector configAttributes = { - EGL_RED_SIZE, (mRedBits >= 0) ? mRedBits : EGL_DONT_CARE, - EGL_GREEN_SIZE, (mGreenBits >= 0) ? mGreenBits : EGL_DONT_CARE, - EGL_BLUE_SIZE, (mBlueBits >= 0) ? mBlueBits : EGL_DONT_CARE, - EGL_ALPHA_SIZE, (mAlphaBits >= 0) ? mAlphaBits : EGL_DONT_CARE, - EGL_DEPTH_SIZE, (mDepthBits >= 0) ? mDepthBits : EGL_DONT_CARE, - EGL_STENCIL_SIZE, (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE, - EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0, - EGL_SAMPLES, (mSamples >= 0) ? mSamples : EGL_DONT_CARE, + EGL_RED_SIZE, + (mConfigParams.redBits >= 0) ? mConfigParams.redBits : EGL_DONT_CARE, + EGL_GREEN_SIZE, + (mConfigParams.greenBits >= 0) ? mConfigParams.greenBits : EGL_DONT_CARE, + EGL_BLUE_SIZE, + (mConfigParams.blueBits >= 0) ? mConfigParams.blueBits : EGL_DONT_CARE, + EGL_ALPHA_SIZE, + (mConfigParams.alphaBits >= 0) ? mConfigParams.alphaBits : EGL_DONT_CARE, + EGL_DEPTH_SIZE, + (mConfigParams.depthBits >= 0) ? mConfigParams.depthBits : EGL_DONT_CARE, + EGL_STENCIL_SIZE, + (mConfigParams.stencilBits >= 0) ? mConfigParams.stencilBits : EGL_DONT_CARE, + EGL_SAMPLE_BUFFERS, + mConfigParams.multisample ? 1 : 0, + EGL_SAMPLES, + (mConfigParams.samples >= 0) ? mConfigParams.samples : EGL_DONT_CARE, }; // Add dynamic attributes bool hasPixelFormatFloat = strstr(displayExtensions, "EGL_EXT_pixel_format_float") != nullptr; - if (!hasPixelFormatFloat && mComponentType != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) + if (!hasPixelFormatFloat && mConfigParams.componentType != EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { destroyGL(); return false; @@ -267,7 +301,7 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library * if (hasPixelFormatFloat) { configAttributes.push_back(EGL_COLOR_COMPONENT_TYPE_EXT); - configAttributes.push_back(mComponentType); + configAttributes.push_back(mConfigParams.componentType); } // Finish the attribute list @@ -280,13 +314,13 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library * return false; } - eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mAlphaBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits); - eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mSamples); + eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mConfigParams.redBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mConfigParams.greenBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mConfigParams.blueBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mConfigParams.alphaBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mConfigParams.depthBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mConfigParams.stencilBits); + eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLES, &mConfigParams.samples); std::vector surfaceAttributes; if (strstr(displayExtensions, "EGL_NV_post_sub_buffer") != nullptr) @@ -297,10 +331,11 @@ bool EGLWindow::initializeDisplayAndSurface(OSWindow *osWindow, angle::Library * bool hasRobustResourceInit = strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization") != nullptr; - if (hasRobustResourceInit && mRobustResourceInit.valid()) + if (hasRobustResourceInit && mConfigParams.robustResourceInit.valid()) { surfaceAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); - surfaceAttributes.push_back(mRobustResourceInit.value() ? EGL_TRUE : EGL_FALSE); + surfaceAttributes.push_back(mConfigParams.robustResourceInit.value() ? EGL_TRUE + : EGL_FALSE); } surfaceAttributes.push_back(EGL_NONE); @@ -331,54 +366,62 @@ EGLContext EGLWindow::createContext(EGLContext share) const if (mClientMajorVersion > 2 && !(mEGLMajorVersion > 1 || mEGLMinorVersion >= 5) && !hasKHRCreateContext) { + std::cerr << "EGL_KHR_create_context incompatibility.\n"; return EGL_NO_CONTEXT; } bool hasWebGLCompatibility = strstr(displayExtensions, "EGL_ANGLE_create_context_webgl_compatibility") != nullptr; - if (mWebGLCompatibility.valid() && !hasWebGLCompatibility) + if (mConfigParams.webGLCompatibility.valid() && !hasWebGLCompatibility) { + std::cerr << "EGL_ANGLE_create_context_webgl_compatibility missing.\n"; return EGL_NO_CONTEXT; } bool hasCreateContextExtensionsEnabled = strstr(displayExtensions, "EGL_ANGLE_create_context_extensions_enabled") != nullptr; - if (mExtensionsEnabled.valid() && !hasCreateContextExtensionsEnabled) + if (mConfigParams.extensionsEnabled.valid() && !hasCreateContextExtensionsEnabled) { + std::cerr << "EGL_ANGLE_create_context_extensions_enabled missing.\n"; return EGL_NO_CONTEXT; } bool hasRobustness = strstr(displayExtensions, "EGL_EXT_create_context_robustness") != nullptr; - if (mRobustAccess && !hasRobustness) + if (mConfigParams.robustAccess && !hasRobustness) { + std::cerr << "EGL_EXT_create_context_robustness missing.\n"; return EGL_NO_CONTEXT; } bool hasBindGeneratesResource = strstr(displayExtensions, "EGL_CHROMIUM_create_context_bind_generates_resource") != nullptr; - if (!mBindGeneratesResource && !hasBindGeneratesResource) + if (!mConfigParams.bindGeneratesResource && !hasBindGeneratesResource) { + std::cerr << "EGL_CHROMIUM_create_context_bind_generates_resource missing.\n"; return EGL_NO_CONTEXT; } bool hasClientArraysExtension = strstr(displayExtensions, "EGL_ANGLE_create_context_client_arrays") != nullptr; - if (!mClientArraysEnabled && !hasClientArraysExtension) + if (!mConfigParams.clientArraysEnabled && !hasClientArraysExtension) { // Non-default state requested without the extension present + std::cerr << "EGL_ANGLE_create_context_client_arrays missing.\n"; return EGL_NO_CONTEXT; } bool hasProgramCacheControlExtension = strstr(displayExtensions, "EGL_ANGLE_program_cache_control ") != nullptr; - if (mContextProgramCacheEnabled.valid() && !hasProgramCacheControlExtension) + if (mConfigParams.contextProgramCacheEnabled.valid() && !hasProgramCacheControlExtension) { + std::cerr << "EGL_ANGLE_program_cache_control missing.\n"; return EGL_NO_CONTEXT; } eglBindAPI(EGL_OPENGL_ES_API); if (eglGetError() != EGL_SUCCESS) { + std::cerr << "Error on eglBindAPI.\n"; return EGL_NO_CONTEXT; } @@ -392,57 +435,61 @@ EGLContext EGLWindow::createContext(EGLContext share) const contextAttributes.push_back(mClientMinorVersion); contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG); - contextAttributes.push_back(mDebug ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.debug ? EGL_TRUE : EGL_FALSE); // TODO(jmadill): Check for the extension string. // bool hasKHRCreateContextNoError = strstr(displayExtensions, // "EGL_KHR_create_context_no_error") != nullptr; contextAttributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR); - contextAttributes.push_back(mNoError ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.noError ? EGL_TRUE : EGL_FALSE); - if (mWebGLCompatibility.valid()) + if (mConfigParams.webGLCompatibility.valid()) { contextAttributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE); - contextAttributes.push_back(mWebGLCompatibility.value() ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.webGLCompatibility.value() ? EGL_TRUE + : EGL_FALSE); } - if (mExtensionsEnabled.valid()) + if (mConfigParams.extensionsEnabled.valid()) { contextAttributes.push_back(EGL_EXTENSIONS_ENABLED_ANGLE); - contextAttributes.push_back(mExtensionsEnabled.value() ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.extensionsEnabled.value() ? EGL_TRUE + : EGL_FALSE); } if (hasRobustness) { contextAttributes.push_back(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT); - contextAttributes.push_back(mRobustAccess ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.robustAccess ? EGL_TRUE : EGL_FALSE); } if (hasBindGeneratesResource) { contextAttributes.push_back(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM); - contextAttributes.push_back(mBindGeneratesResource ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.bindGeneratesResource ? EGL_TRUE : EGL_FALSE); } if (hasClientArraysExtension) { contextAttributes.push_back(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE); - contextAttributes.push_back(mClientArraysEnabled ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.clientArraysEnabled ? EGL_TRUE : EGL_FALSE); } - if (mContextProgramCacheEnabled.valid()) + if (mConfigParams.contextProgramCacheEnabled.valid()) { contextAttributes.push_back(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE); - contextAttributes.push_back(mContextProgramCacheEnabled.value() ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back( + mConfigParams.contextProgramCacheEnabled.value() ? EGL_TRUE : EGL_FALSE); } bool hasRobustResourceInit = strstr(displayExtensions, "EGL_ANGLE_robust_resource_initialization") != nullptr; - if (hasRobustResourceInit && mRobustResourceInit.valid()) + if (hasRobustResourceInit && mConfigParams.robustResourceInit.valid()) { contextAttributes.push_back(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE); - contextAttributes.push_back(mRobustResourceInit.value() ? EGL_TRUE : EGL_FALSE); + contextAttributes.push_back(mConfigParams.robustResourceInit.value() ? EGL_TRUE + : EGL_FALSE); } } contextAttributes.push_back(EGL_NONE); @@ -450,6 +497,7 @@ EGLContext EGLWindow::createContext(EGLContext share) const EGLContext context = eglCreateContext(mDisplay, mConfig, nullptr, &contextAttributes[0]); if (eglGetError() != EGL_SUCCESS) { + std::cerr << "Error on eglCreateContext.\n"; return EGL_NO_CONTEXT; } @@ -468,13 +516,14 @@ bool EGLWindow::initializeContext() eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); if (eglGetError() != EGL_SUCCESS) { + std::cerr << "Error during eglMakeCurrent.\n"; destroyGL(); return false; } - if (mSwapInterval != -1) + if (mConfigParams.swapInterval != -1) { - eglSwapInterval(mDisplay, mSwapInterval); + eglSwapInterval(mDisplay, mConfigParams.swapInterval); } return true; @@ -482,19 +531,8 @@ bool EGLWindow::initializeContext() void EGLWindow::destroyGL() { - if (mSurface != EGL_NO_SURFACE) - { - assert(mDisplay != EGL_NO_DISPLAY); - eglDestroySurface(mDisplay, mSurface); - mSurface = EGL_NO_SURFACE; - } - - if (mContext != EGL_NO_CONTEXT) - { - assert(mDisplay != EGL_NO_DISPLAY); - eglDestroyContext(mDisplay, mContext); - mContext = EGL_NO_CONTEXT; - } + destroyContext(); + destroySurface(); if (mDisplay != EGL_NO_DISPLAY) { @@ -504,6 +542,28 @@ void EGLWindow::destroyGL() } } +void EGLWindow::destroySurface() +{ + if (mSurface != EGL_NO_SURFACE) + { + eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + assert(mDisplay != EGL_NO_DISPLAY); + eglDestroySurface(mDisplay, mSurface); + mSurface = EGL_NO_SURFACE; + } +} + +void EGLWindow::destroyContext() +{ + if (mContext != EGL_NO_CONTEXT) + { + eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + assert(mDisplay != EGL_NO_DISPLAY); + eglDestroyContext(mDisplay, mContext); + mContext = EGL_NO_CONTEXT; + } +} + bool EGLWindow::isGLInitialized() const { return mSurface != EGL_NO_SURFACE && mContext != EGL_NO_CONTEXT && mDisplay != EGL_NO_DISPLAY; diff --git a/util/EGLWindow.h b/util/EGLWindow.h index 55de6eba0..256290a95 100644 --- a/util/EGLWindow.h +++ b/util/EGLWindow.h @@ -26,46 +26,78 @@ class Library; struct PlatformMethods; } // namespace angle +struct ANGLE_UTIL_EXPORT ConfigParameters +{ + ConfigParameters(); + ~ConfigParameters(); + + void reset(); + + // Display parameters. + Optional debugLayersEnabled; + Optional contextVirtualization; + angle::PlatformMethods *platformMethods; + + // Surface and Context parameters. + int redBits; + int greenBits; + int blueBits; + int alphaBits; + int depthBits; + int stencilBits; + int swapInterval; + + Optional webGLCompatibility; + Optional robustResourceInit; + + // EGLWindow-specific. + EGLenum componentType; + bool multisample; + bool debug; + bool noError; + Optional extensionsEnabled; + bool bindGeneratesResource; + bool clientArraysEnabled; + bool robustAccess; + EGLint samples; + Optional contextProgramCacheEnabled; +}; + class ANGLE_UTIL_EXPORT GLWindowBase : angle::NonCopyable { public: static void Delete(GLWindowBase **window); // It should also be possible to set multisample and floating point framebuffers. - void setConfigRedBits(int bits) { mRedBits = bits; } - void setConfigGreenBits(int bits) { mGreenBits = bits; } - void setConfigBlueBits(int bits) { mBlueBits = bits; } - void setConfigAlphaBits(int bits) { mAlphaBits = bits; } - void setConfigDepthBits(int bits) { mDepthBits = bits; } - void setConfigStencilBits(int bits) { mStencilBits = bits; } - void setSwapInterval(int swapInterval) { mSwapInterval = swapInterval; } - - int getConfigRedBits() const { return mRedBits; } - int getConfigGreenBits() const { return mGreenBits; } - int getConfigBlueBits() const { return mBlueBits; } - int getConfigAlphaBits() const { return mAlphaBits; } - int getConfigDepthBits() const { return mDepthBits; } - int getConfigStencilBits() const { return mStencilBits; } - int getSwapInterval() const { return mSwapInterval; } - void setPlatformMethods(angle::PlatformMethods *platformMethods) - { - mPlatformMethods = platformMethods; - } - void setWebGLCompatibilityEnabled(bool webglCompatibility) - { - mWebGLCompatibility = webglCompatibility; - } - void setRobustResourceInit(bool enabled) { mRobustResourceInit = enabled; } - EGLint getClientMajorVersion() const { return mClientMajorVersion; } EGLint getClientMinorVersion() const { return mClientMinorVersion; } - virtual bool initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibrary) = 0; - virtual bool isGLInitialized() const = 0; - virtual void swap() = 0; - virtual void destroyGL() = 0; - virtual void makeCurrent() = 0; - virtual bool hasError() const = 0; + virtual bool initializeGL(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters &config) = 0; + virtual bool isGLInitialized() const = 0; + virtual void swap() = 0; + virtual void destroyGL() = 0; + virtual void makeCurrent() = 0; + virtual bool hasError() const = 0; + + int getConfigRedBits() const { return mConfigParams.redBits; } + int getConfigGreenBits() const { return mConfigParams.greenBits; } + int getConfigBlueBits() const { return mConfigParams.blueBits; } + int getConfigAlphaBits() const { return mConfigParams.alphaBits; } + int getConfigDepthBits() const { return mConfigParams.depthBits; } + int getConfigStencilBits() const { return mConfigParams.stencilBits; } + int getSwapInterval() const { return mConfigParams.swapInterval; } + + bool isMultisample() const { return mConfigParams.multisample; } + bool isDebugEnabled() const { return mConfigParams.debug; } + + const angle::PlatformMethods *getPlatformMethods() const + { + return mConfigParams.platformMethods; + } + + const ConfigParameters &getConfigParams() const { return mConfigParams; } protected: GLWindowBase(EGLint glesMajorVersion, EGLint glesMinorVersion); @@ -73,17 +105,7 @@ class ANGLE_UTIL_EXPORT GLWindowBase : angle::NonCopyable EGLint mClientMajorVersion; EGLint mClientMinorVersion; - int mRedBits; - int mGreenBits; - int mBlueBits; - int mAlphaBits; - int mDepthBits; - int mStencilBits; - int mSwapInterval; - - angle::PlatformMethods *mPlatformMethods; - Optional mWebGLCompatibility; - Optional mRobustResourceInit; + ConfigParameters mConfigParams; }; class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase @@ -94,22 +116,6 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase const EGLPlatformParameters &platform); static void Delete(EGLWindow **window); - void setConfigComponentType(EGLenum componentType) { mComponentType = componentType; } - void setMultisample(bool multisample) { mMultisample = multisample; } - void setSamples(EGLint samples) { mSamples = samples; } - void setDebugEnabled(bool debug) { mDebug = debug; } - void setNoErrorEnabled(bool noError) { mNoError = noError; } - void setExtensionsEnabled(bool extensionsEnabled) { mExtensionsEnabled = extensionsEnabled; } - void setBindGeneratesResource(bool bindGeneratesResource) - { - mBindGeneratesResource = bindGeneratesResource; - } - void setDebugLayersEnabled(bool enabled) { mDebugLayersEnabled = enabled; } - void setClientArraysEnabled(bool enabled) { mClientArraysEnabled = enabled; } - void setRobustAccess(bool enabled) { mRobustAccess = enabled; } - void setContextProgramCacheEnabled(bool enabled) { mContextProgramCacheEnabled = enabled; } - void setContextVirtualization(bool enabled) { mContextVirtualization = enabled; } - static EGLBoolean FindEGLConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *config); void swap() override; @@ -119,15 +125,21 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase EGLDisplay getDisplay() const; EGLSurface getSurface() const; EGLContext getContext() const; - bool isMultisample() const { return mMultisample; } - bool isDebugEnabled() const { return mDebug; } - const angle::PlatformMethods *getPlatformMethods() const { return mPlatformMethods; } // Internally initializes the Display, Surface and Context. - bool initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibrary) override; + bool initializeGL(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) override; - // Only initializes the Display and Surface. - bool initializeDisplayAndSurface(OSWindow *osWindow, angle::Library *glWindowingLibrary); + // Only initializes the Display. + bool initializeDisplay(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms); + + // Only initializes the Surface. + bool initializeSurface(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms); // Create an EGL context with this window's configuration EGLContext createContext(EGLContext share) const; @@ -136,10 +148,14 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase bool initializeContext(); void destroyGL() override; + void destroySurface(); + void destroyContext(); bool isGLInitialized() const override; void makeCurrent() override; bool hasError() const override; + bool isDisplayInitialized() const { return mDisplay != EGL_NO_DISPLAY; } + static bool ClientExtensionEnabled(const std::string &extName); private: @@ -157,18 +173,6 @@ class ANGLE_UTIL_EXPORT EGLWindow : public GLWindowBase EGLint mEGLMajorVersion; EGLint mEGLMinorVersion; EGLPlatformParameters mPlatform; - EGLenum mComponentType; - bool mMultisample; - bool mDebug; - bool mNoError; - Optional mExtensionsEnabled; - bool mBindGeneratesResource; - bool mClientArraysEnabled; - bool mRobustAccess; - EGLint mSamples; - Optional mDebugLayersEnabled; - Optional mContextProgramCacheEnabled; - Optional mContextVirtualization; }; ANGLE_UTIL_EXPORT bool CheckExtensionExists(const char *allExtensions, const std::string &extName); diff --git a/util/windows/WGLWindow.cpp b/util/windows/WGLWindow.cpp index 45f94c3a7..bc66a0bc0 100644 --- a/util/windows/WGLWindow.cpp +++ b/util/windows/WGLWindow.cpp @@ -69,8 +69,11 @@ WGLWindow::WGLWindow(int glesMajorVersion, int glesMinorVersion) WGLWindow::~WGLWindow() {} // Internally initializes GL resources. -bool WGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibrary) +bool WGLWindow::initializeGL(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) { + mConfigParams = params; glWindowingLibrary->getAs("wglGetProcAddress", &gCurrentWGLGetProcAddress); if (!gCurrentWGLGetProcAddress) @@ -135,7 +138,7 @@ bool WGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibr return false; } - if (mWebGLCompatibility.valid() || mRobustResourceInit.valid()) + if (mConfigParams.webGLCompatibility.valid() || mConfigParams.robustResourceInit.valid()) { std::cerr << "WGLWindow does not support the requested feature set." << std::endl; return false; @@ -163,11 +166,11 @@ bool WGLWindow::initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibr makeCurrent(); - if (mSwapInterval != -1) + if (mConfigParams.swapInterval != -1) { if (_wglSwapIntervalEXT) { - if (_wglSwapIntervalEXT(mSwapInterval) == FALSE) + if (_wglSwapIntervalEXT(mConfigParams.swapInterval) == FALSE) { std::cerr << "Error setting swap interval." << std::endl; } diff --git a/util/windows/WGLWindow.h b/util/windows/WGLWindow.h index 8fb976363..0b603cdd3 100644 --- a/util/windows/WGLWindow.h +++ b/util/windows/WGLWindow.h @@ -28,7 +28,9 @@ class ANGLE_UTIL_EXPORT WGLWindow : public GLWindowBase static void Delete(WGLWindow **window); // Internally initializes GL resources. - bool initializeGL(OSWindow *osWindow, angle::Library *glWindowingLibrary) override; + bool initializeGL(OSWindow *osWindow, + angle::Library *glWindowingLibrary, + const ConfigParameters ¶ms) override; void destroyGL() override; bool isGLInitialized() const override;