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
ANGLETest::SetUp();
// This test seems to fail on an nVidia machine when the window is hidden
SetWindowVisible(true);
setWindowVisible(true);
glGenFramebuffers(1, &mFBO);
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
......
......@@ -238,21 +238,7 @@ ANGLETestBase::ANGLETestBase(const angle::PlatformParameters &params)
// Default debug layers to enabled in tests.
mEGLWindow->setDebugLayersEnabled(true);
// Workaround for NVIDIA not being able to share OpenGL and Vulkan contexts.
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;
mCurrentRenderer = params.getRenderer();
}
ANGLETestBase::~ANGLETestBase()
......@@ -277,12 +263,14 @@ void ANGLETestBase::ANGLETestSetUp()
mPlatformContext.ignoreMessages = false;
mPlatformContext.currentTest = this;
OSWindow *osWindow = getOSWindow();
// Resize the window before creating the context so that the first make current
// sets the viewport and scissor box to the right size.
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.";
}
......@@ -296,7 +284,7 @@ void ANGLETestBase::ANGLETestSetUp()
mPlatformMethods.context = &mPlatformContext;
mEGLWindow->setPlatformMethods(&mPlatformMethods);
if (!mEGLWindow->initializeDisplayAndSurface(mOSWindow))
if (!mEGLWindow->initializeDisplayAndSurface(osWindow))
{
FAIL() << "egl display or surface init failed.";
}
......@@ -340,7 +328,8 @@ void ANGLETestBase::ANGLETestTearDown()
FAIL() << "egl error during swap.";
}
mOSWindow->messageLoop();
OSWindow *osWindow = getOSWindow();
osWindow->messageLoop();
if (!destroyEGLContext())
{
......@@ -349,7 +338,7 @@ void ANGLETestBase::ANGLETestTearDown()
// Check for quit message
Event myEvent;
while (mOSWindow->popEvent(&myEvent))
while (osWindow->popEvent(&myEvent))
{
if (myEvent.Type == Event::EVENT_CLOSED)
{
......@@ -790,6 +779,11 @@ bool ANGLETestBase::eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::st
return CheckExtensionExists(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), extName);
}
void ANGLETestBase::setWindowVisible(bool isVisible)
{
getOSWindow()->setVisible(isVisible);
}
void ANGLETestBase::setWindowWidth(int width)
{
mWidth = width;
......@@ -936,36 +930,47 @@ bool ANGLETestBase::destroyEGLContext()
return true;
}
// static
bool ANGLETestBase::InitTestWindow()
OSWindow *ANGLETestBase::getOSWindow()
{
mOSWindow = CreateOSWindow();
if (!mOSWindow->initialize("ANGLE_TEST", 128, 128))
// We only need to separate the Vulkan renderer from others
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
bool ANGLETestBase::DestroyTestWindow()
void ANGLETestBase::DestroyTestWindows()
{
if (mOSWindow)
for (auto it : mOSWindows)
{
mOSWindow->destroy();
delete mOSWindow;
mOSWindow = nullptr;
OSWindow *osWindow = it.second;
std::cerr << "Unexpected nullptr OSWindow" << std::endl;
osWindow->destroy();
delete osWindow;
}
return true;
}
void ANGLETestBase::SetWindowVisible(bool isVisible)
{
mOSWindow->setVisible(isVisible);
mOSWindows.clear();
}
ANGLETest::ANGLETest() : ANGLETestBase(GetParam())
......@@ -1141,18 +1146,9 @@ ANGLETestBase::ScopedIgnorePlatformMessages::~ScopedIgnorePlatformMessages()
mTest->mPlatformContext.ignoreMessages = false;
}
OSWindow *ANGLETestBase::mOSWindow = nullptr;
Optional<EGLint> ANGLETestBase::mLastRendererType;
void ANGLETestEnvironment::SetUp()
{
if (!ANGLETestBase::InitTestWindow())
{
FAIL() << "Failed to create ANGLE test window.";
}
}
std::map<EGLint, OSWindow *> ANGLETestBase::mOSWindows;
void ANGLETestEnvironment::TearDown()
{
ANGLETestBase::DestroyTestWindow();
ANGLETestBase::DestroyTestWindows();
}
......@@ -247,9 +247,7 @@ class ANGLETestBase
virtual ~ANGLETestBase();
public:
static bool InitTestWindow();
static bool DestroyTestWindow();
static void SetWindowVisible(bool isVisible);
static void DestroyTestWindows();
static bool eglDisplayExtensionEnabled(EGLDisplay display, const std::string &extName);
virtual void overrideWorkaroundsD3D(angle::WorkaroundsD3D *workaroundsD3D) {}
......@@ -313,6 +311,7 @@ class ANGLETestBase
static bool eglClientExtensionEnabled(const std::string &extName);
static bool eglDeviceExtensionEnabled(EGLDeviceEXT device, const std::string &extName);
void setWindowVisible(bool isVisible);
void setWindowWidth(int width);
void setWindowHeight(int height);
void setConfigRedBits(int bits);
......@@ -350,7 +349,7 @@ class ANGLETestBase
void ignoreD3D11SDKLayersWarnings();
static OSWindow *GetOSWindow() { return mOSWindow; }
OSWindow *getOSWindow();
GLuint get2DTexturedQuadProgram();
......@@ -396,10 +395,10 @@ class ANGLETestBase
bool mDeferContextInit;
static OSWindow *mOSWindow;
// Workaround for NVIDIA not being able to share a window with OpenGL and Vulkan.
static Optional<EGLint> mLastRendererType;
// 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.
EGLint mCurrentRenderer;
static std::map<int, OSWindow *> mOSWindows;
};
class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::PlatformParameters>
......@@ -415,7 +414,6 @@ class ANGLETest : public ANGLETestBase, public ::testing::TestWithParam<angle::P
class ANGLETestEnvironment : public testing::Environment
{
public:
void SetUp() 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