Commit fad918f8 by Corentin Wallez Committed by Commit Bot

ANGLETest: Reuse test windows per-renderer

When running angle_end2end_tests unfiltered with the OpenGL and Vulkan backends enabled, the test window was recreated all the time and grabbed focus every-time it was created. This made it impossible to do anything with the machine running the tests. Fix this by having one OSWindow per renderer group that's lazily created: this solves most of the issue since only a couple windows end up being created, and at the beginning of the test suite. BUG= Change-Id: I7a51300f0d59d8b6bb79e54d20b3acbf01068002 Reviewed-on: https://chromium-review.googlesource.com/1038433 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 54aafe58
...@@ -29,7 +29,7 @@ class DrawBuffersTest : public ANGLETest ...@@ -29,7 +29,7 @@ class DrawBuffersTest : public ANGLETest
ANGLETest::SetUp(); ANGLETest::SetUp();
// 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_FRAMEBUFFER, mFBO); glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
......
...@@ -238,21 +238,7 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params) ...@@ -238,21 +238,7 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params)
// Default debug layers to enabled in tests. // Default debug layers to enabled in tests.
mEGLWindow->setDebugLayersEnabled(true); mEGLWindow->setDebugLayersEnabled(true);
// Workaround for NVIDIA not being able to share OpenGL and Vulkan contexts. mCurrentRenderer = params.getRenderer();
EGLint renderer = params.getRenderer();
bool needsWindowSwap = mLastRendererType.valid() &&
((renderer != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) !=
(mLastRendererType.value() != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE));
if (needsWindowSwap)
{
DestroyTestWindow();
if (!InitTestWindow())
{
std::cerr << "Failed to create ANGLE test window.";
}
}
mLastRendererType = renderer;
} }
ANGLETestBase::~ANGLETestBase() ANGLETestBase::~ANGLETestBase()
...@@ -277,12 +263,14 @@ void ANGLETestBase::ANGLETestSetUp() ...@@ -277,12 +263,14 @@ void ANGLETestBase::ANGLETestSetUp()
mPlatformContext.ignoreMessages = false; mPlatformContext.ignoreMessages = false;
mPlatformContext.currentTest = this; mPlatformContext.currentTest = this;
OSWindow *osWindow = getOSWindow();
// 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 (osWindow->getWidth() != mWidth || osWindow->getHeight() != mHeight)
{ {
if (!mOSWindow->resize(mWidth, mHeight)) if (!osWindow->resize(mWidth, mHeight))
{ {
FAIL() << "Failed to resize ANGLE test window."; FAIL() << "Failed to resize ANGLE test window.";
} }
...@@ -296,7 +284,7 @@ void ANGLETestBase::ANGLETestSetUp() ...@@ -296,7 +284,7 @@ void ANGLETestBase::ANGLETestSetUp()
mPlatformMethods.context = &mPlatformContext; mPlatformMethods.context = &mPlatformContext;
mEGLWindow->setPlatformMethods(&mPlatformMethods); mEGLWindow->setPlatformMethods(&mPlatformMethods);
if (!mEGLWindow->initializeDisplayAndSurface(mOSWindow)) if (!mEGLWindow->initializeDisplayAndSurface(osWindow))
{ {
FAIL() << "egl display or surface init failed."; FAIL() << "egl display or surface init failed.";
} }
...@@ -340,7 +328,8 @@ void ANGLETestBase::ANGLETestTearDown() ...@@ -340,7 +328,8 @@ void ANGLETestBase::ANGLETestTearDown()
FAIL() << "egl error during swap."; FAIL() << "egl error during swap.";
} }
mOSWindow->messageLoop(); OSWindow *osWindow = getOSWindow();
osWindow->messageLoop();
if (!destroyEGLContext()) if (!destroyEGLContext())
{ {
...@@ -349,7 +338,7 @@ void ANGLETestBase::ANGLETestTearDown() ...@@ -349,7 +338,7 @@ void ANGLETestBase::ANGLETestTearDown()
// Check for quit message // Check for quit message
Event myEvent; Event myEvent;
while (mOSWindow->popEvent(&myEvent)) while (osWindow->popEvent(&myEvent))
{ {
if (myEvent.Type == Event::EVENT_CLOSED) if (myEvent.Type == Event::EVENT_CLOSED)
{ {
...@@ -790,6 +779,11 @@ bool ANGLETestBase::eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::st ...@@ -790,6 +779,11 @@ bool ANGLETestBase::eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::st
return CheckExtensionExists(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), extName); return CheckExtensionExists(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), extName);
} }
void ANGLETestBase::setWindowVisible(bool isVisible)
{
getOSWindow()->setVisible(isVisible);
}
void ANGLETestBase::setWindowWidth(int width) void ANGLETestBase::setWindowWidth(int width)
{ {
mWidth = width; mWidth = width;
...@@ -936,36 +930,47 @@ bool ANGLETestBase::destroyEGLContext() ...@@ -936,36 +930,47 @@ bool ANGLETestBase::destroyEGLContext()
return true; return true;
} }
// static OSWindow *ANGLETestBase::getOSWindow()
bool ANGLETestBase::InitTestWindow()
{ {
mOSWindow = CreateOSWindow(); // We only need to separate the Vulkan renderer from others
if (!mOSWindow->initialize("ANGLE_TEST", 128, 128)) int rendererIndex = 0;
if (mCurrentRenderer == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
rendererIndex = 1;
}
// The same renderer can always reuse a window.
auto it = mOSWindows.find(rendererIndex);
if (it != mOSWindows.end())
{ {
return false; return it->second;
} }
mOSWindow->setVisible(true); // Create a new window for this renderer, tagged with the renderer name
OSWindow *osWindow = CreateOSWindow();
std::string name = "ANGLE_TEST";
if (!osWindow->initialize(name, 128, 128))
{
std::cerr << "Failed to initialize test window" << std::endl;
return nullptr;
}
osWindow->setVisible(true);
return true; mOSWindows[rendererIndex] = osWindow;
return osWindow;
} }
// static // static
bool ANGLETestBase::DestroyTestWindow() void ANGLETestBase::DestroyTestWindows()
{ {
if (mOSWindow) for (auto it : mOSWindows)
{ {
mOSWindow->destroy(); OSWindow *osWindow = it.second;
delete mOSWindow; std::cerr << "Unexpected nullptr OSWindow" << std::endl;
mOSWindow = nullptr; osWindow->destroy();
delete osWindow;
} }
return true; mOSWindows.clear();
}
void ANGLETestBase::SetWindowVisible(bool isVisible)
{
mOSWindow->setVisible(isVisible);
} }
ANGLETest::ANGLETest() : ANGLETestBase(GetParam()) ANGLETest::ANGLETest() : ANGLETestBase(GetParam())
...@@ -1141,18 +1146,9 @@ ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages() ...@@ -1141,18 +1146,9 @@ ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
mTest->mPlatformContext.ignoreMessages = false; mTest->mPlatformContext.ignoreMessages = false;
} }
OSWindow *ANGLETestBase::mOSWindow = nullptr; std::map<EGLint, OSWindow *> ANGLETestBase::mOSWindows;
Optional<EGLint> ANGLETestBase::mLastRendererType;
void ANGLETestEnvironment::SetUp()
{
if (!ANGLETestBase::InitTestWindow())
{
FAIL() << "Failed to create ANGLE test window.";
}
}
void ANGLETestEnvironment::TearDown() void ANGLETestEnvironment::TearDown()
{ {
ANGLETestBase::DestroyTestWindow(); ANGLETestBase::DestroyTestWindows();
} }
...@@ -247,9 +247,7 @@ class ANGLETestBase ...@@ -247,9 +247,7 @@ class ANGLETestBase
virtual ~ANGLETestBase(); virtual ~ANGLETestBase();
public: public:
static bool InitTestWindow(); static void DestroyTestWindows();
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) {}
...@@ -313,6 +311,7 @@ class ANGLETestBase ...@@ -313,6 +311,7 @@ class ANGLETestBase
static bool eglClientExtensionEnabled(const std::string &extName); static bool eglClientExtensionEnabled(const std::string &extName);
static bool eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName); static bool eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName);
void setWindowVisible(bool isVisible);
void setWindowWidth(int width); void setWindowWidth(int width);
void setWindowHeight(int height); void setWindowHeight(int height);
void setConfigRedBits(int bits); void setConfigRedBits(int bits);
...@@ -350,7 +349,7 @@ class ANGLETestBase ...@@ -350,7 +349,7 @@ class ANGLETestBase
void ignoreD3D11SDKLayersWarnings(); void ignoreD3D11SDKLayersWarnings();
static OSWindow *GetOSWindow() { return mOSWindow; } OSWindow *getOSWindow();
GLuint get2DTexturedQuadProgram(); GLuint get2DTexturedQuadProgram();
...@@ -396,10 +395,10 @@ class ANGLETestBase ...@@ -396,10 +395,10 @@ class ANGLETestBase
bool mDeferContextInit; bool mDeferContextInit;
static OSWindow *mOSWindow; // Using the same window for both Vulkan and OpenGL crashes on the NVIDIA driver so we use one
// OS window lazily-created per group of renderer.
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan. EGLint mCurrentRenderer;
static Optional<EGLint> mLastRendererType; static std::map<int, OSWindow *> mOSWindows;
}; };
class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::PlatformParameters> class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::PlatformParameters>
...@@ -415,7 +414,6 @@ class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::P ...@@ -415,7 +414,6 @@ class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::P
class ANGLETestEnvironment : public testing::Environment class ANGLETestEnvironment : public testing::Environment
{ {
public: public:
void SetUp() override;
void TearDown() override; void TearDown() override;
}; };
......
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