Commit f455f756 by Jamie Madill Committed by Commit Bot

Reuse angle_end2end_test windows and displays.

This both speeds up test execution and cuts down on the number of new windows and displays created for a test config. This feature is only currently enabled for Windows NVIDIA and Intel. On every other config there were blocking issues that would need investigation. Several tests were manually flagged as needed new displays on each iteration to prevent test flakiness. This feature might fix the issues with Intel test flakiness that have been prominent on the ANGLE CQ. WGL configurations have also been removed from ANGLE tests. So this removes more of the code from ANGLETest.cpp. Bug: angleproject:3261 Change-Id: Ic2864d4806ad38e0eeaa3c0afcd54ae1c548090f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1520995 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 45938b61
...@@ -2869,11 +2869,7 @@ Error ValidateSwapBuffersWithDamageKHR(const Display *display, ...@@ -2869,11 +2869,7 @@ Error ValidateSwapBuffersWithDamageKHR(const Display *display,
EGLint *rects, EGLint *rects,
EGLint n_rects) EGLint n_rects)
{ {
Error error = ValidateSurface(display, surface); ANGLE_TRY(ValidateSurface(display, surface));
if (error.isError())
{
return error;
}
if (!display->getExtensions().swapBuffersWithDamage) if (!display->getExtensions().swapBuffersWithDamage)
{ {
......
...@@ -78,7 +78,11 @@ EGLsizeiANDROID GetBlob(const void *key, ...@@ -78,7 +78,11 @@ EGLsizeiANDROID GetBlob(const void *key,
class EGLBlobCacheTest : public ANGLETest class EGLBlobCacheTest : public ANGLETest
{ {
protected: protected:
EGLBlobCacheTest() : mHasBlobCache(false) {} EGLBlobCacheTest() : mHasBlobCache(false)
{
// Force disply caching off. Blob cache functions require it.
forceNewDisplay();
}
void SetUp() override void SetUp() override
{ {
...@@ -88,8 +92,6 @@ class EGLBlobCacheTest : public ANGLETest ...@@ -88,8 +92,6 @@ class EGLBlobCacheTest : public ANGLETest
mHasBlobCache = eglDisplayExtensionEnabled(display, kEGLExtName); mHasBlobCache = eglDisplayExtensionEnabled(display, kEGLExtName);
} }
void TearDown() override { ANGLETest::TearDown(); }
bool programBinaryAvailable() bool programBinaryAvailable()
{ {
return (getClientMajorVersion() >= 3 || extensionEnabled("GL_OES_get_program_binary")); return (getClientMajorVersion() >= 3 || extensionEnabled("GL_OES_get_program_binary"));
...@@ -103,7 +105,7 @@ TEST_P(EGLBlobCacheTest, Functional) ...@@ -103,7 +105,7 @@ TEST_P(EGLBlobCacheTest, Functional)
{ {
EGLDisplay display = getEGLWindow()->getDisplay(); EGLDisplay display = getEGLWindow()->getDisplay();
EXPECT_EQ(true, mHasBlobCache); EXPECT_TRUE(mHasBlobCache);
eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob); eglSetBlobCacheFuncsANDROID(display, SetBlob, GetBlob);
ASSERT_EGL_SUCCESS(); ASSERT_EGL_SUCCESS();
...@@ -172,7 +174,7 @@ void main() ...@@ -172,7 +174,7 @@ void main()
// Tests error conditions of the APIs. // Tests error conditions of the APIs.
TEST_P(EGLBlobCacheTest, NegativeAPI) TEST_P(EGLBlobCacheTest, NegativeAPI)
{ {
EXPECT_EQ(true, mHasBlobCache); EXPECT_TRUE(mHasBlobCache);
// Test bad display // Test bad display
eglSetBlobCacheFuncsANDROID(EGL_NO_DISPLAY, nullptr, nullptr); eglSetBlobCacheFuncsANDROID(EGL_NO_DISPLAY, nullptr, nullptr);
......
...@@ -31,25 +31,34 @@ class EGLProgramCacheControlTest : public ANGLETest ...@@ -31,25 +31,34 @@ class EGLProgramCacheControlTest : public ANGLETest
} }
protected: protected:
EGLProgramCacheControlTest() { setDeferContextInit(true); } EGLProgramCacheControlTest()
{
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
setDeferContextInit(true);
}
void SetUp() override void SetUp() override
{ {
mPlatformMethods.cacheProgram = &TestCacheProgram; setContextProgramCacheEnabled(true, &TestCacheProgram);
ANGLETest::SetUp(); ANGLETest::SetUp();
if (extensionAvailable()) if (extensionAvailable())
{ {
EGLDisplay display = getEGLWindow()->getDisplay(); EGLDisplay display = getEGLWindow()->getDisplay();
setContextProgramCacheEnabled(true);
eglProgramCacheResizeANGLE(display, kEnabledCacheSize, EGL_PROGRAM_CACHE_RESIZE_ANGLE); eglProgramCacheResizeANGLE(display, kEnabledCacheSize, EGL_PROGRAM_CACHE_RESIZE_ANGLE);
ASSERT_EGL_SUCCESS();
} }
getEGLWindow()->initializeContext(); ASSERT_TRUE(getEGLWindow()->initializeContext());
} }
void TearDown() override { ANGLETest::TearDown(); } void TearDown() override
{
setContextProgramCacheEnabled(false, angle::DefaultCacheProgram);
ANGLETest::TearDown();
}
bool extensionAvailable() bool extensionAvailable()
{ {
......
...@@ -57,7 +57,7 @@ class DrawBuffersTest : public ANGLETest ...@@ -57,7 +57,7 @@ class DrawBuffersTest : public ANGLETest
} }
// This test seems to fail on an nVidia machine when the window is hidden // This test seems to fail on an nVidia machine when the window is hidden
SetWindowVisible(true); setWindowVisible(true);
glGenFramebuffers(1, &mFBO); glGenFramebuffers(1, &mFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFBO);
......
...@@ -115,7 +115,7 @@ class InstancingTest : public ANGLETest ...@@ -115,7 +115,7 @@ class InstancingTest : public ANGLETest
// TODO: Fix these. http://anglebug.com/3129 // TODO: Fix these. http://anglebug.com/3129
ANGLE_SKIP_TEST_IF(IsD3D9() && draw == Indexed && geometry == Point); ANGLE_SKIP_TEST_IF(IsD3D9() && draw == Indexed && geometry == Point);
ANGLE_SKIP_TEST_IF(IsD3D9() && IsAMD() && geometry == Point); ANGLE_SKIP_TEST_IF(IsD3D9() && IsAMD());
// D3D11 FL9_3 has a special codepath that emulates instanced points rendering // D3D11 FL9_3 has a special codepath that emulates instanced points rendering
// but it has bugs and was only implemented for vertex positions in a buffer object, // but it has bugs and was only implemented for vertex positions in a buffer object,
......
...@@ -28,6 +28,9 @@ class ProgramBinaryTest : public ANGLETest ...@@ -28,6 +28,9 @@ class ProgramBinaryTest : public ANGLETest
setConfigGreenBits(8); setConfigGreenBits(8);
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
} }
void SetUp() override void SetUp() override
...@@ -52,7 +55,6 @@ class ProgramBinaryTest : public ANGLETest ...@@ -52,7 +55,6 @@ class ProgramBinaryTest : public ANGLETest
{ {
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
glDeleteBuffers(1, &mBuffer); glDeleteBuffers(1, &mBuffer);
ANGLETest::TearDown(); ANGLETest::TearDown();
} }
...@@ -259,6 +261,12 @@ ANGLE_INSTANTIATE_TEST(ProgramBinaryTest, ...@@ -259,6 +261,12 @@ ANGLE_INSTANTIATE_TEST(ProgramBinaryTest,
class ProgramBinaryES3Test : public ANGLETest class ProgramBinaryES3Test : public ANGLETest
{ {
protected: protected:
ProgramBinaryES3Test()
{
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
}
void testBinaryAndUBOBlockIndexes(bool drawWithProgramFirst); void testBinaryAndUBOBlockIndexes(bool drawWithProgramFirst);
}; };
...@@ -368,6 +376,9 @@ class ProgramBinaryES31Test : public ANGLETest ...@@ -368,6 +376,9 @@ class ProgramBinaryES31Test : public ANGLETest
setConfigGreenBits(8); setConfigGreenBits(8);
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
} }
}; };
......
...@@ -29,6 +29,9 @@ class RobustBufferAccessBehaviorTest : public ANGLETest ...@@ -29,6 +29,9 @@ class RobustBufferAccessBehaviorTest : public ANGLETest
setConfigGreenBits(8); setConfigGreenBits(8);
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
} }
void TearDown() override void TearDown() override
......
...@@ -204,6 +204,9 @@ class RobustResourceInitTest : public ANGLETest ...@@ -204,6 +204,9 @@ class RobustResourceInitTest : public ANGLETest
setConfigStencilBits(8); setConfigStencilBits(8);
setRobustResourceInit(true); setRobustResourceInit(true);
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
} }
bool hasGLExtension() { return extensionEnabled("GL_ANGLE_robust_resource_initialization"); } bool hasGLExtension() { return extensionEnabled("GL_ANGLE_robust_resource_initialization"); }
......
...@@ -65,6 +65,9 @@ class ShaderStorageBufferTest31 : public ANGLETest ...@@ -65,6 +65,9 @@ class ShaderStorageBufferTest31 : public ANGLETest
setConfigGreenBits(8); setConfigGreenBits(8);
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
// Test flakiness was noticed when reusing displays.
forceNewDisplay();
} }
void runMatrixTest(const MatrixCase &matrixCase) void runMatrixTest(const MatrixCase &matrixCase)
...@@ -1590,6 +1593,9 @@ TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue) ...@@ -1590,6 +1593,9 @@ TEST_P(ShaderStorageBufferTest31, LoadAndStoreBooleanValue)
// http://anglebug.com/1951 // http://anglebug.com/1951
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux()); ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux());
// Seems to fail on Windows NVIDIA GL when tests are run without interruption.
ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsOpenGL());
constexpr char kComputeShaderSource[] = R"(#version 310 es constexpr char kComputeShaderSource[] = R"(#version 310 es
layout (local_size_x=1) in; layout (local_size_x=1) in;
layout(binding=0, std140) buffer Storage0 layout(binding=0, std140) buffer Storage0
......
...@@ -68,7 +68,7 @@ TEST_P(TextureRectangleTest, TexImage2D) ...@@ -68,7 +68,7 @@ TEST_P(TextureRectangleTest, TexImage2D)
// Defining a texture of the max size is allowed // Defining a texture of the max size is allowed
{ {
ScopedIgnorePlatformMessages ignore(this); ScopedIgnorePlatformMessages ignore;
glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA, glTexImage2D(GL_TEXTURE_RECTANGLE_ANGLE, 0, GL_RGBA, maxSize, maxSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr); GL_UNSIGNED_BYTE, nullptr);
...@@ -154,7 +154,7 @@ TEST_P(TextureRectangleTest, TexStorage2D) ...@@ -154,7 +154,7 @@ TEST_P(TextureRectangleTest, TexStorage2D)
// Defining a texture of the max size is allowed but still allow for OOM // Defining a texture of the max size is allowed but still allow for OOM
{ {
ScopedIgnorePlatformMessages ignore(this); ScopedIgnorePlatformMessages ignore;
GLTexture tex; GLTexture tex;
glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex); glBindTexture(GL_TEXTURE_RECTANGLE_ANGLE, tex);
......
...@@ -14,10 +14,6 @@ ...@@ -14,10 +14,6 @@
#include "util/EGLWindow.h" #include "util/EGLWindow.h"
#include "util/OSWindow.h" #include "util/OSWindow.h"
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
# include "util/windows/WGLWindow.h"
#endif // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
#if defined(ANGLE_PLATFORM_WINDOWS) #if defined(ANGLE_PLATFORM_WINDOWS)
# include <VersionHelpers.h> # include <VersionHelpers.h>
#endif // defined(ANGLE_PLATFORM_WINDOWS) #endif // defined(ANGLE_PLATFORM_WINDOWS)
...@@ -172,6 +168,15 @@ const char *GetColorName(GLColor color) ...@@ -172,6 +168,15 @@ const char *GetColorName(GLColor color)
return nullptr; return nullptr;
} }
bool ShouldAlwaysForceNewDisplay()
{
// We prefer to reuse config displays. This is faster and solves a driver issue where creating
// many displays causes crashes. However this exposes other driver bugs on many other platforms.
// Conservatively enable the feature only on Windows Intel and NVIDIA for now.
SystemInfo *systemInfo = GetTestSystemInfo();
return (!systemInfo || !IsWindows() || systemInfo->hasAMDGPU());
}
} // anonymous namespace } // anonymous namespace
GLColorRGB::GLColorRGB() : R(0), G(0), B(0) {} GLColorRGB::GLColorRGB() : R(0), G(0), B(0) {}
...@@ -278,9 +283,17 @@ GLColor32F ReadColor32F(GLint x, GLint y) ...@@ -278,9 +283,17 @@ GLColor32F ReadColor32F(GLint x, GLint y)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
return actual; return actual;
} }
} // namespace angle } // namespace angle
namespace
{
angle::PlatformMethods gDefaultPlatformMethods;
TestPlatformContext gPlatformContext;
// After a fixed number of iterations we reset the test window. This works around some driver bugs.
constexpr uint32_t kWindowReuseLimit = 50;
} // anonymous namespace
// static // static
std::array<angle::Vector3, 6> ANGLETestBase::GetQuadVertices() std::array<angle::Vector3, 6> ANGLETestBase::GetQuadVertices()
{ {
...@@ -300,45 +313,62 @@ std::array<angle::Vector3, 4> ANGLETestBase::GetIndexedQuadVertices() ...@@ -300,45 +313,62 @@ std::array<angle::Vector3, 4> ANGLETestBase::GetIndexedQuadVertices()
} }
ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params) ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params)
: mEGLWindow(nullptr), : mWidth(16),
mWGLWindow(nullptr),
mWidth(16),
mHeight(16), mHeight(16),
mIgnoreD3D11SDKLayersWarnings(false), mIgnoreD3D11SDKLayersWarnings(false),
mQuadVertexBuffer(0), mQuadVertexBuffer(0),
mQuadIndexBuffer(0), mQuadIndexBuffer(0),
m2DTexturedQuadProgram(0), m2DTexturedQuadProgram(0),
m3DTexturedQuadProgram(0), m3DTexturedQuadProgram(0),
mDeferContextInit(false) mDeferContextInit(false),
mAlwaysForceNewDisplay(angle::ShouldAlwaysForceNewDisplay()),
mForceNewDisplay(mAlwaysForceNewDisplay),
mCurrentPlatform(nullptr)
{ {
switch (params.driver) auto iter = gPlatforms.find(params);
if (iter != gPlatforms.end())
{ {
case angle::GLESDriverType::AngleEGL: mCurrentPlatform = &iter->second;
{ mCurrentPlatform->configParams.reset();
mEGLWindow =
EGLWindow::New(params.majorVersion, params.minorVersion, params.eglParameters);
// Default debug layers to enabled in tests. // Default debug layers to enabled in tests.
mConfigParameters.debugLayersEnabled = true; mCurrentPlatform->configParams.debugLayersEnabled = true;
return;
}
// Workaround for NVIDIA not being able to share OpenGL and Vulkan contexts. Platform platform;
// Workaround if any of the GPUs is Nvidia, since we can't detect current GPU. auto insertIter = gPlatforms.emplace(params, platform);
EGLint renderer = params.getRenderer(); mCurrentPlatform = &insertIter.first->second;
bool needsWindowSwap =
hasNVIDIAGPU() && mLastRendererType.valid() &&
((renderer != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) !=
(mLastRendererType.value() != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE));
if (needsWindowSwap) std::stringstream windowNameStream;
{ windowNameStream << "ANGLE Tests - " << params;
DestroyTestWindow(); std::string windowName = windowNameStream.str();
if (!InitTestWindow())
{ if (mAlwaysForceNewDisplay)
std::cerr << "Failed to create ANGLE test window."; {
} mCurrentPlatform->osWindow = mOSWindowSingleton;
} }
mLastRendererType = renderer; if (!mCurrentPlatform->osWindow)
{
mCurrentPlatform->osWindow = OSWindow::New();
if (!mCurrentPlatform->osWindow->initialize(windowName.c_str(), 128, 128))
{
std::cerr << "Failed to initialize OS Window.";
}
mOSWindowSingleton = mCurrentPlatform->osWindow;
}
// On Linux we must keep the test windows visible. On Windows it doesn't seem to need it.
mCurrentPlatform->osWindow->setVisible(!angle::IsWindows());
switch (params.driver)
{
case angle::GLESDriverType::AngleEGL:
{
mCurrentPlatform->eglWindow =
EGLWindow::New(params.majorVersion, params.minorVersion, params.eglParameters);
break; break;
} }
...@@ -350,14 +380,14 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params) ...@@ -350,14 +380,14 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params)
case angle::GLESDriverType::SystemWGL: case angle::GLESDriverType::SystemWGL:
{ {
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS) // WGL tests are currently disabled.
mWGLWindow = WGLWindow::New(params.majorVersion, params.minorVersion);
#else
std::cerr << "Unsupported driver." << std::endl; std::cerr << "Unsupported driver." << std::endl;
#endif // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
break; break;
} }
} }
// Default debug layers to enabled in tests.
mCurrentPlatform->configParams.debugLayersEnabled = true;
} }
ANGLETestBase::~ANGLETestBase() ANGLETestBase::~ANGLETestBase()
...@@ -378,81 +408,63 @@ ANGLETestBase::~ANGLETestBase() ...@@ -378,81 +408,63 @@ ANGLETestBase::~ANGLETestBase()
{ {
glDeleteProgram(m3DTexturedQuadProgram); glDeleteProgram(m3DTexturedQuadProgram);
} }
EGLWindow::Delete(&mEGLWindow);
#if defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
WGLWindow::Delete(&mWGLWindow);
#endif // defined(ANGLE_USE_UTIL_LOADER) && defined(ANGLE_PLATFORM_WINDOWS)
} }
void ANGLETestBase::ANGLETestSetUp() void ANGLETestBase::ANGLETestSetUp()
{ {
mPlatformContext.ignoreMessages = false; gDefaultPlatformMethods.overrideWorkaroundsD3D = angle::TestPlatform_overrideWorkaroundsD3D;
mPlatformContext.warningsAsErrors = false; gDefaultPlatformMethods.overrideFeaturesVk = angle::TestPlatform_overrideFeaturesVk;
mPlatformContext.currentTest = this; gDefaultPlatformMethods.logError = angle::TestPlatform_logError;
gDefaultPlatformMethods.logWarning = angle::TestPlatform_logWarning;
gDefaultPlatformMethods.logInfo = angle::TestPlatform_logInfo;
gDefaultPlatformMethods.context = &gPlatformContext;
mCurrentPlatform->configParams.platformMethods = &gDefaultPlatformMethods;
gPlatformContext.ignoreMessages = false;
gPlatformContext.warningsAsErrors = false;
gPlatformContext.currentTest = this;
// Resize the window before creating the context so that the first make current // Resize the window before creating the context so that the first make current
// sets the viewport and scissor box to the right size. // sets the viewport and scissor box to the right size.
bool needSwap = false; bool needSwap = false;
if (mOSWindow->getWidth() != mWidth || mOSWindow->getHeight() != mHeight) if (mCurrentPlatform->osWindow->getWidth() != mWidth ||
mCurrentPlatform->osWindow->getHeight() != mHeight)
{ {
if (!mOSWindow->resize(mWidth, mHeight)) if (!mCurrentPlatform->osWindow->resize(mWidth, mHeight))
{ {
FAIL() << "Failed to resize ANGLE test window."; FAIL() << "Failed to resize ANGLE test window.";
} }
needSwap = true; needSwap = true;
} }
if (mWGLWindow) // WGL tests are currently disabled.
if (mCurrentPlatform->wglWindow)
{ {
#if defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary(),
mConfigParameters))
{
std::cerr << "WGL init failed.. trying again with new OSWindow." << std::endl;
// Retry once with a fresh OSWindow. This is necessary to work around a bug in the
// NVIDIA WGL implementation. It seems sometimes the pixel format gets stuck. Using
// a new windows seems to allow us to set the new pixel format correctly.
DestroyTestWindow();
if (!InitTestWindow())
{
FAIL() << "Failed to create ANGLE test window.";
}
if (!mWGLWindow->initializeGL(mOSWindow, ANGLETestEnvironment::GetWGLLibrary(),
mConfigParameters))
{
FAIL() << "WGL init failed.";
}
}
#else
FAIL() << "Unsupported driver."; FAIL() << "Unsupported driver.";
#endif // defined(ANGLE_PLATFORM_WINDOWS) && defined(ANGLE_USE_UTIL_LOADER)
} }
else else
{ {
mPlatformMethods.overrideWorkaroundsD3D = angle::TestPlatform_overrideWorkaroundsD3D; if (mForceNewDisplay || !mCurrentPlatform->eglWindow->isDisplayInitialized() ||
mPlatformMethods.overrideFeaturesVk = angle::TestPlatform_overrideFeaturesVk; !ConfigParameters::CanShareDisplay(mCurrentPlatform->configParams,
mPlatformMethods.logError = angle::TestPlatform_logError; mCurrentPlatform->eglWindow->getConfigParams()))
mPlatformMethods.logWarning = angle::TestPlatform_logWarning;
mPlatformMethods.logInfo = angle::TestPlatform_logInfo;
mPlatformMethods.context = &mPlatformContext;
mConfigParameters.platformMethods = &mPlatformMethods;
if (!mEGLWindow->initializeDisplay(mOSWindow, ANGLETestEnvironment::GetEGLLibrary(),
mConfigParameters))
{ {
FAIL() << "egl display init failed."; mCurrentPlatform->eglWindow->destroyGL();
if (!mCurrentPlatform->eglWindow->initializeDisplay(
mCurrentPlatform->osWindow, ANGLETestEnvironment::GetEGLLibrary(),
mCurrentPlatform->configParams))
{
FAIL() << "egl display init failed.";
}
} }
if (!mEGLWindow->initializeSurface(mOSWindow, ANGLETestEnvironment::GetEGLLibrary(), if (!mCurrentPlatform->eglWindow->initializeSurface(mCurrentPlatform->osWindow,
mConfigParameters)) ANGLETestEnvironment::GetEGLLibrary(),
mCurrentPlatform->configParams))
{ {
FAIL() << "egl surface init failed."; FAIL() << "egl surface init failed.";
} }
if (!mDeferContextInit && !mEGLWindow->initializeContext()) if (!mDeferContextInit && !mCurrentPlatform->eglWindow->initializeContext())
{ {
FAIL() << "GL Context init failed."; FAIL() << "GL Context init failed.";
} }
...@@ -477,26 +489,33 @@ void ANGLETestBase::ANGLETestSetUp() ...@@ -477,26 +489,33 @@ void ANGLETestBase::ANGLETestSetUp()
void ANGLETestBase::ANGLETestTearDown() void ANGLETestBase::ANGLETestTearDown()
{ {
if (mEGLWindow) gPlatformContext.currentTest = nullptr;
{
mConfigParameters.platformMethods = nullptr;
checkD3D11SDKLayersMessages();
}
mPlatformContext.currentTest = nullptr;
const auto &info = testing::UnitTest::GetInstance()->current_test_info(); const testing::TestInfo *info = testing::UnitTest::GetInstance()->current_test_info();
angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name()); angle::WriteDebugMessage("Exiting %s.%s\n", info->test_case_name(), info->name());
swapBuffers(); swapBuffers();
mCurrentPlatform->osWindow->messageLoop();
mOSWindow->messageLoop(); if (mCurrentPlatform->eglWindow)
{
checkD3D11SDKLayersMessages();
}
getGLWindow()->destroyGL(); if (mCurrentPlatform->reuseCounter++ >= kWindowReuseLimit || mForceNewDisplay)
{
mCurrentPlatform->reuseCounter = 0;
getGLWindow()->destroyGL();
}
else
{
mCurrentPlatform->eglWindow->destroyContext();
mCurrentPlatform->eglWindow->destroySurface();
}
// Check for quit message // Check for quit message
Event myEvent; Event myEvent;
while (mOSWindow->popEvent(&myEvent)) while (mCurrentPlatform->osWindow->popEvent(&myEvent))
{ {
if (myEvent.Type == Event::EVENT_CLOSED) if (myEvent.Type == Event::EVENT_CLOSED)
{ {
...@@ -511,7 +530,7 @@ void ANGLETestBase::swapBuffers() ...@@ -511,7 +530,7 @@ void ANGLETestBase::swapBuffers()
{ {
getGLWindow()->swap(); getGLWindow()->swap();
if (mEGLWindow) if (mCurrentPlatform->eglWindow)
{ {
EXPECT_EGL_SUCCESS(); EXPECT_EGL_SUCCESS();
} }
...@@ -863,14 +882,15 @@ void ANGLETestBase::checkD3D11SDKLayersMessages() ...@@ -863,14 +882,15 @@ void ANGLETestBase::checkD3D11SDKLayersMessages()
// On Windows D3D11, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages // On Windows D3D11, check ID3D11InfoQueue to see if any D3D11 SDK Layers messages
// were outputted by the test. We enable the Debug layers in Release tests as well. // were outputted by the test. We enable the Debug layers in Release tests as well.
if (mIgnoreD3D11SDKLayersWarnings || if (mIgnoreD3D11SDKLayersWarnings ||
mEGLWindow->getPlatform().renderer != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE || mCurrentPlatform->eglWindow->getPlatform().renderer !=
mEGLWindow->getDisplay() == EGL_NO_DISPLAY) EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE ||
mCurrentPlatform->eglWindow->getDisplay() == EGL_NO_DISPLAY)
{ {
return; return;
} }
const char *extensionString = const char *extensionString = static_cast<const char *>(
static_cast<const char *>(eglQueryString(mEGLWindow->getDisplay(), EGL_EXTENSIONS)); eglQueryString(mCurrentPlatform->eglWindow->getDisplay(), EGL_EXTENSIONS));
if (!extensionString) if (!extensionString)
{ {
std::cout << "Error getting extension string from EGL Window." << std::endl; std::cout << "Error getting extension string from EGL Window." << std::endl;
...@@ -895,7 +915,8 @@ void ANGLETestBase::checkD3D11SDKLayersMessages() ...@@ -895,7 +915,8 @@ void ANGLETestBase::checkD3D11SDKLayersMessages()
ASSERT_NE(nullptr, queryDisplayAttribEXT); ASSERT_NE(nullptr, queryDisplayAttribEXT);
ASSERT_NE(nullptr, queryDeviceAttribEXT); ASSERT_NE(nullptr, queryDeviceAttribEXT);
ASSERT_EGL_TRUE(queryDisplayAttribEXT(mEGLWindow->getDisplay(), EGL_DEVICE_EXT, &angleDevice)); ASSERT_EGL_TRUE(queryDisplayAttribEXT(mCurrentPlatform->eglWindow->getDisplay(), EGL_DEVICE_EXT,
&angleDevice));
ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), ASSERT_EGL_TRUE(queryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
EGL_D3D11_DEVICE_ANGLE, &device)); EGL_D3D11_DEVICE_ANGLE, &device));
ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device); ID3D11Device *d3d11Device = reinterpret_cast<ID3D11Device *>(device);
...@@ -936,12 +957,6 @@ void ANGLETestBase::checkD3D11SDKLayersMessages() ...@@ -936,12 +957,6 @@ void ANGLETestBase::checkD3D11SDKLayersMessages()
#endif // defined(ANGLE_PLATFORM_WINDOWS) #endif // defined(ANGLE_PLATFORM_WINDOWS)
} }
bool ANGLETestBase::hasNVIDIAGPU() const
{
angle::SystemInfo *systemInfo = angle::GetTestSystemInfo();
return systemInfo && systemInfo->hasNVIDIAGPU();
}
bool ANGLETestBase::extensionEnabled(const std::string &extName) bool ANGLETestBase::extensionEnabled(const std::string &extName)
{ {
return CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)), return CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
...@@ -994,107 +1009,116 @@ void ANGLETestBase::setWindowHeight(int height) ...@@ -994,107 +1009,116 @@ void ANGLETestBase::setWindowHeight(int height)
GLWindowBase *ANGLETestBase::getGLWindow() const GLWindowBase *ANGLETestBase::getGLWindow() const
{ {
return mWGLWindow ? reinterpret_cast<GLWindowBase *>(mWGLWindow) : mEGLWindow; // WGL tests are currently disabled.
assert(!mCurrentPlatform->wglWindow);
return mCurrentPlatform->eglWindow;
} }
void ANGLETestBase::setConfigRedBits(int bits) void ANGLETestBase::setConfigRedBits(int bits)
{ {
mConfigParameters.redBits = bits; mCurrentPlatform->configParams.redBits = bits;
} }
void ANGLETestBase::setConfigGreenBits(int bits) void ANGLETestBase::setConfigGreenBits(int bits)
{ {
mConfigParameters.greenBits = bits; mCurrentPlatform->configParams.greenBits = bits;
} }
void ANGLETestBase::setConfigBlueBits(int bits) void ANGLETestBase::setConfigBlueBits(int bits)
{ {
mConfigParameters.blueBits = bits; mCurrentPlatform->configParams.blueBits = bits;
} }
void ANGLETestBase::setConfigAlphaBits(int bits) void ANGLETestBase::setConfigAlphaBits(int bits)
{ {
mConfigParameters.alphaBits = bits; mCurrentPlatform->configParams.alphaBits = bits;
} }
void ANGLETestBase::setConfigDepthBits(int bits) void ANGLETestBase::setConfigDepthBits(int bits)
{ {
mConfigParameters.depthBits = bits; mCurrentPlatform->configParams.depthBits = bits;
} }
void ANGLETestBase::setConfigStencilBits(int bits) void ANGLETestBase::setConfigStencilBits(int bits)
{ {
mConfigParameters.stencilBits = bits; mCurrentPlatform->configParams.stencilBits = bits;
} }
void ANGLETestBase::setConfigComponentType(EGLenum componentType) void ANGLETestBase::setConfigComponentType(EGLenum componentType)
{ {
mConfigParameters.componentType = componentType; mCurrentPlatform->configParams.componentType = componentType;
} }
void ANGLETestBase::setMultisampleEnabled(bool enabled) void ANGLETestBase::setMultisampleEnabled(bool enabled)
{ {
mConfigParameters.multisample = enabled; mCurrentPlatform->configParams.multisample = enabled;
} }
void ANGLETestBase::setSamples(EGLint samples) void ANGLETestBase::setSamples(EGLint samples)
{ {
mConfigParameters.samples = samples; mCurrentPlatform->configParams.samples = samples;
} }
void ANGLETestBase::setDebugEnabled(bool enabled) void ANGLETestBase::setDebugEnabled(bool enabled)
{ {
mConfigParameters.debug = enabled; mCurrentPlatform->configParams.debug = enabled;
} }
void ANGLETestBase::setNoErrorEnabled(bool enabled) void ANGLETestBase::setNoErrorEnabled(bool enabled)
{ {
mConfigParameters.noError = enabled; mCurrentPlatform->configParams.noError = enabled;
} }
void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility) void ANGLETestBase::setWebGLCompatibilityEnabled(bool webglCompatibility)
{ {
mConfigParameters.webGLCompatibility = webglCompatibility; mCurrentPlatform->configParams.webGLCompatibility = webglCompatibility;
} }
void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled) void ANGLETestBase::setExtensionsEnabled(bool extensionsEnabled)
{ {
mConfigParameters.extensionsEnabled = extensionsEnabled; mCurrentPlatform->configParams.extensionsEnabled = extensionsEnabled;
} }
void ANGLETestBase::setRobustAccess(bool enabled) void ANGLETestBase::setRobustAccess(bool enabled)
{ {
mConfigParameters.robustAccess = enabled; mCurrentPlatform->configParams.robustAccess = enabled;
} }
void ANGLETestBase::setBindGeneratesResource(bool bindGeneratesResource) void ANGLETestBase::setBindGeneratesResource(bool bindGeneratesResource)
{ {
mConfigParameters.bindGeneratesResource = bindGeneratesResource; mCurrentPlatform->configParams.bindGeneratesResource = bindGeneratesResource;
} }
void ANGLETestBase::setDebugLayersEnabled(bool enabled) void ANGLETestBase::setDebugLayersEnabled(bool enabled)
{ {
mConfigParameters.debugLayersEnabled = enabled; mCurrentPlatform->configParams.debugLayersEnabled = enabled;
} }
void ANGLETestBase::setClientArraysEnabled(bool enabled) void ANGLETestBase::setClientArraysEnabled(bool enabled)
{ {
mConfigParameters.clientArraysEnabled = enabled; mCurrentPlatform->configParams.clientArraysEnabled = enabled;
} }
void ANGLETestBase::setRobustResourceInit(bool enabled) void ANGLETestBase::setRobustResourceInit(bool enabled)
{ {
mConfigParameters.robustResourceInit = enabled; mCurrentPlatform->configParams.robustResourceInit = enabled;
} }
void ANGLETestBase::setContextProgramCacheEnabled(bool enabled) void ANGLETestBase::setContextProgramCacheEnabled(bool enabled,
angle::CacheProgramFunc cacheProgramFunc)
{ {
mConfigParameters.contextProgramCacheEnabled = enabled; mCurrentPlatform->configParams.contextProgramCacheEnabled = enabled;
gDefaultPlatformMethods.cacheProgram = cacheProgramFunc;
} }
void ANGLETestBase::setContextVirtualization(bool enabled) void ANGLETestBase::setContextVirtualization(bool enabled)
{ {
mConfigParameters.contextVirtualization = enabled; mCurrentPlatform->configParams.contextVirtualization = enabled;
}
void ANGLETestBase::forceNewDisplay()
{
mForceNewDisplay = true;
} }
void ANGLETestBase::setDeferContextInit(bool enabled) void ANGLETestBase::setDeferContextInit(bool enabled)
...@@ -1114,7 +1138,7 @@ int ANGLETestBase::getClientMinorVersion() const ...@@ -1114,7 +1138,7 @@ int ANGLETestBase::getClientMinorVersion() const
EGLWindow *ANGLETestBase::getEGLWindow() const EGLWindow *ANGLETestBase::getEGLWindow() const
{ {
return mEGLWindow; return mCurrentPlatform->eglWindow;
} }
int ANGLETestBase::getWindowWidth() const int ANGLETestBase::getWindowWidth() const
...@@ -1129,38 +1153,12 @@ int ANGLETestBase::getWindowHeight() const ...@@ -1129,38 +1153,12 @@ int ANGLETestBase::getWindowHeight() const
bool ANGLETestBase::isMultisampleEnabled() const bool ANGLETestBase::isMultisampleEnabled() const
{ {
return mEGLWindow->isMultisample(); return mCurrentPlatform->eglWindow->isMultisample();
} }
// static void ANGLETestBase::setWindowVisible(bool isVisible)
bool ANGLETestBase::InitTestWindow()
{
mOSWindow = OSWindow::New();
if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
{
return false;
}
mOSWindow->setVisible(true);
return true;
}
// static
bool ANGLETestBase::DestroyTestWindow()
{
if (mOSWindow)
{
mOSWindow->destroy();
OSWindow::Delete(&mOSWindow);
}
return true;
}
void ANGLETestBase::SetWindowVisible(bool isVisible)
{ {
mOSWindow->setVisible(isVisible); mCurrentPlatform->osWindow->setVisible(isVisible);
} }
bool IsIntel() bool IsIntel()
...@@ -1256,10 +1254,13 @@ bool IsRelease() ...@@ -1256,10 +1254,13 @@ bool IsRelease()
return !IsDebug(); return !IsDebug();
} }
ANGLETestBase::Platform::Platform() = default;
ANGLETestBase::Platform::~Platform() = default;
EGLint ANGLETestBase::getPlatformRenderer() const EGLint ANGLETestBase::getPlatformRenderer() const
{ {
assert(mEGLWindow); assert(mCurrentPlatform->eglWindow);
return mEGLWindow->getPlatform().renderer; return mCurrentPlatform->eglWindow->getPlatform().renderer;
} }
void ANGLETestBase::ignoreD3D11SDKLayersWarnings() void ANGLETestBase::ignoreD3D11SDKLayersWarnings()
...@@ -1273,39 +1274,30 @@ void ANGLETestBase::treatPlatformWarningsAsErrors() ...@@ -1273,39 +1274,30 @@ void ANGLETestBase::treatPlatformWarningsAsErrors()
#if defined(ANGLE_PLATFORM_WINDOWS) #if defined(ANGLE_PLATFORM_WINDOWS)
// Only do warnings-as-errors on 8 and above. We may fall back to the old // Only do warnings-as-errors on 8 and above. We may fall back to the old
// compiler DLL on Windows 7. // compiler DLL on Windows 7.
mPlatformContext.warningsAsErrors = IsWindows8OrGreater(); gPlatformContext.warningsAsErrors = IsWindows8OrGreater();
#endif // defined(ANGLE_PLATFORM_WINDOWS) #endif // defined(ANGLE_PLATFORM_WINDOWS)
} }
ANGLETestBase::ScopedIgnorePlatformMessages::ScopedIgnorePlatformMessages(ANGLETestBase *test) ANGLETestBase::ScopedIgnorePlatformMessages::ScopedIgnorePlatformMessages()
: mTest(test)
{ {
mTest->mPlatformContext.ignoreMessages = true; gPlatformContext.ignoreMessages = true;
} }
ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages() ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
{ {
mTest->mPlatformContext.ignoreMessages = false; gPlatformContext.ignoreMessages = false;
} }
OSWindow *ANGLETestBase::mOSWindow = nullptr; OSWindow *ANGLETestBase::mOSWindowSingleton = nullptr;
std::map<angle::PlatformParameters, ANGLETestBase::Platform> ANGLETestBase::gPlatforms;
Optional<EGLint> ANGLETestBase::mLastRendererType; Optional<EGLint> ANGLETestBase::mLastRendererType;
std::unique_ptr<angle::Library> ANGLETestEnvironment::gEGLLibrary; std::unique_ptr<angle::Library> ANGLETestEnvironment::gEGLLibrary;
std::unique_ptr<angle::Library> ANGLETestEnvironment::gWGLLibrary; std::unique_ptr<angle::Library> ANGLETestEnvironment::gWGLLibrary;
void ANGLETestEnvironment::SetUp() void ANGLETestEnvironment::SetUp() {}
{
if (!ANGLETestBase::InitTestWindow())
{
FAIL() << "Failed to create ANGLE test window.";
}
}
void ANGLETestEnvironment::TearDown() void ANGLETestEnvironment::TearDown() {}
{
ANGLETestBase::DestroyTestWindow();
}
angle::Library *ANGLETestEnvironment::GetEGLLibrary() angle::Library *ANGLETestEnvironment::GetEGLLibrary()
{ {
......
...@@ -262,9 +262,7 @@ class ANGLETestBase ...@@ -262,9 +262,7 @@ class ANGLETestBase
virtual ~ANGLETestBase(); virtual ~ANGLETestBase();
public: public:
static bool InitTestWindow(); void setWindowVisible(bool isVisible);
static bool DestroyTestWindow();
static void SetWindowVisible(bool isVisible);
static bool eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName); static bool eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName);
virtual void overrideWorkaroundsD3D(angle::WorkaroundsD3D *workaroundsD3D) {} virtual void overrideWorkaroundsD3D(angle::WorkaroundsD3D *workaroundsD3D) {}
...@@ -357,8 +355,9 @@ class ANGLETestBase ...@@ -357,8 +355,9 @@ class ANGLETestBase
void setDebugLayersEnabled(bool enabled); void setDebugLayersEnabled(bool enabled);
void setClientArraysEnabled(bool enabled); void setClientArraysEnabled(bool enabled);
void setRobustResourceInit(bool enabled); void setRobustResourceInit(bool enabled);
void setContextProgramCacheEnabled(bool enabled); void setContextProgramCacheEnabled(bool enabled, angle::CacheProgramFunc cacheProgramFunc);
void setContextVirtualization(bool enabled); void setContextVirtualization(bool enabled);
void forceNewDisplay();
// Some EGL extension tests would like to defer the Context init until the test body. // Some EGL extension tests would like to defer the Context init until the test body.
void setDeferContextInit(bool enabled); void setDeferContextInit(bool enabled);
...@@ -379,28 +378,22 @@ class ANGLETestBase ...@@ -379,28 +378,22 @@ class ANGLETestBase
// Allows a test to be more restrictive about platform warnings. // Allows a test to be more restrictive about platform warnings.
void treatPlatformWarningsAsErrors(); void treatPlatformWarningsAsErrors();
static OSWindow *GetOSWindow() { return mOSWindow; } OSWindow *getOSWindow() { return mCurrentPlatform->osWindow; }
GLuint get2DTexturedQuadProgram(); GLuint get2DTexturedQuadProgram();
// Has a float uniform "u_layer" to choose the 3D texture layer. // Has a float uniform "u_layer" to choose the 3D texture layer.
GLuint get3DTexturedQuadProgram(); GLuint get3DTexturedQuadProgram();
angle::PlatformMethods mPlatformMethods;
class ScopedIgnorePlatformMessages : angle::NonCopyable class ScopedIgnorePlatformMessages : angle::NonCopyable
{ {
public: public:
ScopedIgnorePlatformMessages(ANGLETestBase *test); ScopedIgnorePlatformMessages();
~ScopedIgnorePlatformMessages(); ~ScopedIgnorePlatformMessages();
private:
ANGLETestBase *mTest;
}; };
private: private:
void checkD3D11SDKLayersMessages(); void checkD3D11SDKLayersMessages();
bool hasNVIDIAGPU() const;
void drawQuad(GLuint program, void drawQuad(GLuint program,
const std::string &positionAttribName, const std::string &positionAttribName,
...@@ -410,9 +403,18 @@ class ANGLETestBase ...@@ -410,9 +403,18 @@ class ANGLETestBase
bool useInstancedDrawCalls, bool useInstancedDrawCalls,
GLuint numInstances); GLuint numInstances);
EGLWindow *mEGLWindow; struct Platform
WGLWindow *mWGLWindow; {
ConfigParameters mConfigParameters; Platform();
~Platform();
EGLWindow *eglWindow = nullptr;
WGLWindow *wglWindow = nullptr;
OSWindow *osWindow = nullptr;
ConfigParameters configParams;
uint32_t reuseCounter = 0;
};
int mWidth; int mWidth;
int mHeight; int mHeight;
...@@ -426,11 +428,17 @@ class ANGLETestBase ...@@ -426,11 +428,17 @@ class ANGLETestBase
GLuint m2DTexturedQuadProgram; GLuint m2DTexturedQuadProgram;
GLuint m3DTexturedQuadProgram; GLuint m3DTexturedQuadProgram;
TestPlatformContext mPlatformContext;
bool mDeferContextInit; bool mDeferContextInit;
bool mAlwaysForceNewDisplay;
bool mForceNewDisplay;
// On most systems we force a new display on every test instance. For these configs we can
// share a single OSWindow instance. With display reuse we need a separate OSWindow for each
// different config. This OSWindow sharing seemed to lead to driver bugs on some platforms.
static OSWindow *mOSWindowSingleton;
static OSWindow *mOSWindow; static std::map<angle::PlatformParameters, Platform> gPlatforms;
Platform *mCurrentPlatform;
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan. // Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
static Optional<EGLint> mLastRendererType; static Optional<EGLint> mLastRendererType;
......
...@@ -114,6 +114,14 @@ void ConfigParameters::reset() ...@@ -114,6 +114,14 @@ void ConfigParameters::reset()
*this = ConfigParameters(); *this = ConfigParameters();
} }
// static
bool ConfigParameters::CanShareDisplay(const ConfigParameters &a, const ConfigParameters &b)
{
return a.debugLayersEnabled == b.debugLayersEnabled &&
a.contextVirtualization == b.contextVirtualization &&
a.platformMethods == b.platformMethods;
}
// GLWindowBase implementation. // GLWindowBase implementation.
GLWindowBase::GLWindowBase(EGLint glesMajorVersion, EGLint glesMinorVersion) GLWindowBase::GLWindowBase(EGLint glesMajorVersion, EGLint glesMinorVersion)
: mClientMajorVersion(glesMajorVersion), mClientMinorVersion(glesMinorVersion) : mClientMajorVersion(glesMajorVersion), mClientMinorVersion(glesMinorVersion)
......
...@@ -33,6 +33,8 @@ struct ANGLE_UTIL_EXPORT ConfigParameters ...@@ -33,6 +33,8 @@ struct ANGLE_UTIL_EXPORT ConfigParameters
void reset(); void reset();
static bool CanShareDisplay(const ConfigParameters &a, const ConfigParameters &b);
// Display parameters. // Display parameters.
Optional<bool> debugLayersEnabled; Optional<bool> debugLayersEnabled;
Optional<bool> contextVirtualization; Optional<bool> contextVirtualization;
......
...@@ -550,7 +550,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh ...@@ -550,7 +550,7 @@ bool Win32Window::initialize(const std::string &name, size_t width, size_t heigh
} }
DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU; DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
DWORD parentExtendedStyle = WS_EX_APPWINDOW; DWORD parentExtendedStyle = WS_EX_APPWINDOW | WS_EX_TOOLWINDOW;
RECT sizeRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)}; RECT sizeRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle); AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment