Commit 837dd9ab by apatrick@chromium.org

Do not set a WNDPROC on a window created by another thread.

It turns out SetWindowLong succeeds for other threads in the same process but we do not want the WNDPROC to be called from threads other than the thread on which EGL is running on. This was one of the reasons --in-process-gpu was not working with ANGLE in Chrome. Review URL: http://codereview.appspot.com/4576045 git-svn-id: https://angleproject.googlecode.com/svn/trunk@677 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 79169b5a
#define MAJOR_VERSION 0
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 673
#define BUILD_REVISION 677
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -251,11 +251,14 @@ HWND Surface::getWindowHandle()
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
if (message == WM_SIZE) {
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
{
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
if(surf) {
surf->checkForOutOfDateSwapChain();
if(surf)
{
surf->checkForOutOfDateSwapChain();
}
}
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
......@@ -264,42 +267,55 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
void Surface::subclassWindow()
{
if (!mWindow)
return;
if (!mWindow)
{
return;
}
SetLastError(0);
LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
mWindowSubclassed = false;
return;
}
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
SetLastError(0);
LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false;
return;
}
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
}
void Surface::unsubclassWindow()
{
if(!mWindowSubclassed)
return;
// un-subclass
LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
// Check the windowproc is still SurfaceWindowProc.
// If this assert fails, then it is likely the application has subclassed the
// hwnd as well and did not unsubclass before destroying its EGL context. The
// application should be modified to either subclass before initializing the
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc) {
LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
}
if(!mWindowSubclassed)
{
return;
}
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
// un-subclass
LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
// Check the windowproc is still SurfaceWindowProc.
// If this assert fails, then it is likely the application has subclassed the
// hwnd as well and did not unsubclass before destroying its EGL context. The
// application should be modified to either subclass before initializing the
// EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc)
{
LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
}
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
}
bool Surface::checkForOutOfDateSwapChain()
......
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