Manually apply fix for SL-17474 Device context not properly released at shutdown

meow-7.2.2
Ansariel 2022-05-30 19:19:32 +02:00
parent 3c0df154f7
commit e60b6e45e4
1 changed files with 28 additions and 20 deletions

View File

@ -877,21 +877,20 @@ void LLWindowWin32::close()
// Restore gamma to the system values.
restoreGamma();
if (mhDC)
{
if (!ReleaseDC(mWindowHandle, mhDC))
{
LL_WARNS("Window") << "Release of mhDC failed" << LL_ENDL;
}
mhDC = NULL;
}
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
mWindowThread->post([=]()
{
if (IsWindow(mWindowHandle))
{
if (mhDC)
{
if (!ReleaseDC(mWindowHandle, mhDC))
{
LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL;
}
}
// Make sure we don't leave a blank toolbar button.
ShowWindow(mWindowHandle, SW_HIDE);
@ -917,6 +916,7 @@ void LLWindowWin32::close()
// Even though the above lambda might not yet have run, we've already
// bound mWindowHandle into it by value, which should suffice for the
// operations we're asking. That's the last time WE should touch it.
mhDC = NULL;
mWindowHandle = NULL;
mWindowThread->close();
}
@ -1509,12 +1509,10 @@ const S32 max_format = (S32)num_formats - 1;
{
wglDeleteContext (mhRC); // Release The Rendering Context
mhRC = 0; // Zero The Rendering Context
}
ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
mhDC = 0; // Zero The Device Context
}
// will release and recreate mhDC, mWindowHandle
recreateWindow(window_rect, dw_ex_style, dw_style);
RECT rect;
@ -1664,7 +1662,8 @@ const S32 max_format = (S32)num_formats - 1;
void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style)
{
auto oldHandle = mWindowHandle;
auto oldWindowHandle = mWindowHandle;
auto oldDCHandle = mhDC;
// zero out mWindowHandle and mhDC before destroying window so window
// thread falls back to peekmessage
@ -1676,7 +1675,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
auto window_work =
[this,
self=mWindowThread,
oldHandle,
oldWindowHandle,
oldDCHandle,
// bind CreateWindowEx() parameters by value instead of
// back-referencing LLWindowWin32 members
windowClassName=mWindowClassName,
@ -1692,11 +1692,19 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
self->mWindowHandle = 0;
self->mhDC = 0;
// important to call DestroyWindow() from the window thread
if (oldHandle && !destroy_window_handler(oldHandle))
if (oldWindowHandle)
{
LL_WARNS("Window") << "Failed to properly close window before recreating it!"
<< LL_ENDL;
if (oldDCHandle && !ReleaseDC(oldWindowHandle, oldDCHandle))
{
LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL;
}
// important to call DestroyWindow() from the window thread
if (!destroy_window_handler(oldWindowHandle))
{
LL_WARNS("Window") << "Failed to properly close window before recreating it!"
<< LL_ENDL;
}
}
auto handle = CreateWindowEx(dw_ex_style,
@ -1734,7 +1742,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
};
// But how we pass window_work to the window thread depends on whether we
// already have a window handle.
if (! oldHandle)
if (!oldWindowHandle)
{
// Pass window_work using the WorkQueue: without an existing window
// handle, the window thread can't call GetMessage().
@ -1747,7 +1755,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw
// PostMessage(oldHandle) because oldHandle won't be destroyed until
// the window thread has retrieved and executed window_work.
LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL;
mWindowThread->Post(oldHandle, window_work);
mWindowThread->Post(oldWindowHandle, window_work);
}
auto future = promise.get_future();