Commit 22a5f5f0 by Geoff Lang Committed by Commit Bot

Make sure to destroy all resources in DisplayWGL if initialization fails.

It was possible to leak some resources if initialization fails half way through. BUG=angleproject:2546 Change-Id: I0ea75a274fed27b118e788785bb72aff5fe8381e Reviewed-on: https://chromium-review.googlesource.com/1070221Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 2a12b3d5
...@@ -76,8 +76,7 @@ DisplayWGL::DisplayWGL(const egl::DisplayState &state) ...@@ -76,8 +76,7 @@ DisplayWGL::DisplayWGL(const egl::DisplayState &state)
mDxgiModule(nullptr), mDxgiModule(nullptr),
mD3d11Module(nullptr), mD3d11Module(nullptr),
mD3D11DeviceHandle(nullptr), mD3D11DeviceHandle(nullptr),
mD3D11Device(nullptr), mD3D11Device(nullptr)
mDisplay(nullptr)
{ {
} }
...@@ -87,8 +86,18 @@ DisplayWGL::~DisplayWGL() ...@@ -87,8 +86,18 @@ DisplayWGL::~DisplayWGL()
egl::Error DisplayWGL::initialize(egl::Display *display) egl::Error DisplayWGL::initialize(egl::Display *display)
{ {
mDisplay = display; egl::Error error = initializeImpl(display);
if (error.isError())
{
destroy();
return error;
}
return DisplayGL::initialize(display);
}
egl::Error DisplayWGL::initializeImpl(egl::Display *display)
{
mOpenGLModule = LoadLibraryA("opengl32.dll"); mOpenGLModule = LoadLibraryA("opengl32.dll");
if (!mOpenGLModule) if (!mOpenGLModule)
{ {
...@@ -105,7 +114,7 @@ egl::Error DisplayWGL::initialize(egl::Display *display) ...@@ -105,7 +114,7 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
const LPSTR idcArrow = MAKEINTRESOURCEA(32512); const LPSTR idcArrow = MAKEINTRESOURCEA(32512);
std::ostringstream stream; std::ostringstream stream;
stream << "ANGLE DisplayWGL " << gl::FmtHex(mDisplay) << " Intermediate Window Class"; stream << "ANGLE DisplayWGL " << gl::FmtHex(display) << " Intermediate Window Class";
std::string className = stream.str(); std::string className = stream.str();
WNDCLASSA intermediateClassDesc = { 0 }; WNDCLASSA intermediateClassDesc = { 0 };
...@@ -122,22 +131,15 @@ egl::Error DisplayWGL::initialize(egl::Display *display) ...@@ -122,22 +131,15 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
mWindowClass = RegisterClassA(&intermediateClassDesc); mWindowClass = RegisterClassA(&intermediateClassDesc);
if (!mWindowClass) if (!mWindowClass)
{ {
return egl::EglNotInitialized() << "Failed to register intermediate OpenGL window class, " return egl::EglNotInitialized()
<< gl::FmtErr(HRESULT_CODE(GetLastError())); << "Failed to register intermediate OpenGL window class \"" << className.c_str()
} << "\":" << gl::FmtErr(HRESULT_CODE(GetLastError()));
}
HWND dummyWindow = CreateWindowExA(0,
reinterpret_cast<const char *>(mWindowClass), HWND dummyWindow =
"ANGLE Dummy Window", CreateWindowExA(0, reinterpret_cast<const char *>(mWindowClass), "ANGLE Dummy Window",
WS_OVERLAPPEDWINDOW, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, nullptr, nullptr);
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
nullptr,
nullptr,
nullptr,
nullptr);
if (!dummyWindow) if (!dummyWindow)
{ {
return egl::EglNotInitialized() << "Failed to create dummy OpenGL window."; return egl::EglNotInitialized() << "Failed to create dummy OpenGL window.";
...@@ -201,18 +203,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display) ...@@ -201,18 +203,10 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
} }
// Create the real intermediate context and windows // Create the real intermediate context and windows
mWindow = CreateWindowExA(0, mWindow = CreateWindowExA(0, reinterpret_cast<const char *>(mWindowClass),
reinterpret_cast<const char *>(mWindowClass), "ANGLE Intermediate Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
"ANGLE Intermediate Window", CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr,
WS_OVERLAPPEDWINDOW, nullptr, nullptr);
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
nullptr,
nullptr,
nullptr,
nullptr);
if (!mWindow) if (!mWindow)
{ {
return egl::EglNotInitialized() << "Failed to create intermediate OpenGL window."; return egl::EglNotInitialized() << "Failed to create intermediate OpenGL window.";
...@@ -253,7 +247,6 @@ egl::Error DisplayWGL::initialize(egl::Display *display) ...@@ -253,7 +247,6 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
if (mFunctionsWGL->createContextAttribsARB) if (mFunctionsWGL->createContextAttribsARB)
{ {
mWGLContext = initializeContextAttribs(displayAttributes); mWGLContext = initializeContextAttribs(displayAttributes);
} }
...@@ -326,34 +319,63 @@ egl::Error DisplayWGL::initialize(egl::Display *display) ...@@ -326,34 +319,63 @@ egl::Error DisplayWGL::initialize(egl::Display *display)
} }
} }
return DisplayGL::initialize(display); return egl::NoError();
} }
void DisplayWGL::terminate() void DisplayWGL::terminate()
{ {
DisplayGL::terminate(); DisplayGL::terminate();
destroy();
}
void DisplayWGL::destroy()
{
releaseD3DDevice(mD3D11DeviceHandle); releaseD3DDevice(mD3D11DeviceHandle);
if (mFunctionsWGL)
{
if (mDeviceContext)
{
mFunctionsWGL->makeCurrent(mDeviceContext, nullptr); mFunctionsWGL->makeCurrent(mDeviceContext, nullptr);
mCurrentDC = nullptr; }
if (mWGLContext)
{
mFunctionsWGL->deleteContext(mWGLContext); mFunctionsWGL->deleteContext(mWGLContext);
}
}
mCurrentDC = nullptr;
mWGLContext = nullptr; mWGLContext = nullptr;
SafeDelete(mFunctionsWGL);
SafeDelete(mFunctionsGL);
if (mDeviceContext)
{
ReleaseDC(mWindow, mDeviceContext); ReleaseDC(mWindow, mDeviceContext);
mDeviceContext = nullptr; mDeviceContext = nullptr;
}
if (mWindow)
{
DestroyWindow(mWindow); DestroyWindow(mWindow);
mWindow = nullptr; mWindow = nullptr;
}
UnregisterClassA(reinterpret_cast<const char *>(mWindowClass), nullptr); if (mWindowClass)
{
if (!UnregisterClassA(reinterpret_cast<const char *>(mWindowClass),
GetModuleHandle(nullptr)))
{
WARN() << "Failed to unregister OpenGL window class: " << gl::FmtHex(mWindowClass);
}
mWindowClass = NULL; mWindowClass = NULL;
}
SafeDelete(mFunctionsWGL); if (mOpenGLModule)
SafeDelete(mFunctionsGL); {
FreeLibrary(mOpenGLModule); FreeLibrary(mOpenGLModule);
mOpenGLModule = nullptr; mOpenGLModule = nullptr;
}
SafeRelease(mD3D11Device); SafeRelease(mD3D11Device);
...@@ -456,10 +478,10 @@ egl::ConfigSet DisplayWGL::generateConfigs() ...@@ -456,10 +478,10 @@ egl::ConfigSet DisplayWGL::generateConfigs()
bool supportsES3 = maxVersion >= gl::Version(3, 0); bool supportsES3 = maxVersion >= gl::Version(3, 0);
PIXELFORMATDESCRIPTOR pixelFormatDescriptor; PIXELFORMATDESCRIPTOR pixelFormatDescriptor;
DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor), &pixelFormatDescriptor); DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor),
&pixelFormatDescriptor);
auto getAttrib = [this](int attrib) auto getAttrib = [this](int attrib) {
{
return wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, attrib, mFunctionsWGL); return wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, attrib, mFunctionsWGL);
}; };
...@@ -468,7 +490,8 @@ egl::ConfigSet DisplayWGL::generateConfigs() ...@@ -468,7 +490,8 @@ egl::ConfigSet DisplayWGL::generateConfigs()
egl::Config config; egl::Config config;
config.renderTargetFormat = GL_RGBA8; // TODO: use the bit counts to determine the format config.renderTargetFormat = GL_RGBA8; // TODO: use the bit counts to determine the format
config.depthStencilFormat = GL_DEPTH24_STENCIL8; // TODO: use the bit counts to determine the format config.depthStencilFormat =
GL_DEPTH24_STENCIL8; // TODO: use the bit counts to determine the format
config.bufferSize = pixelFormatDescriptor.cColorBits; config.bufferSize = pixelFormatDescriptor.cColorBits;
config.redSize = pixelFormatDescriptor.cRedBits; config.redSize = pixelFormatDescriptor.cRedBits;
config.greenSize = pixelFormatDescriptor.cGreenBits; config.greenSize = pixelFormatDescriptor.cGreenBits;
...@@ -543,7 +566,7 @@ egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration, ...@@ -543,7 +566,7 @@ egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration,
{ {
case EGL_D3D_TEXTURE_ANGLE: case EGL_D3D_TEXTURE_ANGLE:
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
ANGLE_TRY(const_cast<DisplayWGL*>(this)->initializeD3DDevice()); ANGLE_TRY(const_cast<DisplayWGL *>(this)->initializeD3DDevice());
return D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(buftype, clientBuffer, return D3DTextureSurfaceWGL::ValidateD3DTextureClientBuffer(buftype, clientBuffer,
mD3D11Device); mD3D11Device);
...@@ -554,7 +577,7 @@ egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration, ...@@ -554,7 +577,7 @@ egl::Error DisplayWGL::validateClientBuffer(const egl::Config *configuration,
std::string DisplayWGL::getVendorString() const std::string DisplayWGL::getVendorString() const
{ {
//UNIMPLEMENTED(); // UNIMPLEMENTED();
return ""; return "";
} }
......
...@@ -67,6 +67,9 @@ class DisplayWGL : public DisplayGL ...@@ -67,6 +67,9 @@ class DisplayWGL : public DisplayGL
void releaseD3DDevice(HANDLE handle); void releaseD3DDevice(HANDLE handle);
private: private:
egl::Error initializeImpl(egl::Display *display);
void destroy();
const FunctionsGL *getFunctionsGL() const override; const FunctionsGL *getFunctionsGL() const override;
egl::Error initializeD3DDevice(); egl::Error initializeD3DDevice();
...@@ -108,8 +111,6 @@ class DisplayWGL : public DisplayGL ...@@ -108,8 +111,6 @@ class DisplayWGL : public DisplayGL
size_t refCount; size_t refCount;
}; };
std::map<IUnknown *, D3DObjectHandle> mRegisteredD3DDevices; std::map<IUnknown *, D3DObjectHandle> mRegisteredD3DDevices;
egl::Display *mDisplay;
}; };
} }
......
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