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 MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 673 #define BUILD_REVISION 677
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -251,10 +251,13 @@ HWND Surface::getWindowHandle() ...@@ -251,10 +251,13 @@ HWND Surface::getWindowHandle()
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
if (message == WM_SIZE) { {
if (message == WM_SIZE)
{
Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty)); Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
if(surf) { if(surf)
{
surf->checkForOutOfDateSwapChain(); surf->checkForOutOfDateSwapChain();
} }
} }
...@@ -265,11 +268,21 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam ...@@ -265,11 +268,21 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
void Surface::subclassWindow() void Surface::subclassWindow()
{ {
if (!mWindow) if (!mWindow)
{
return; return;
}
DWORD processId;
DWORD threadId = GetWindowThreadProcessId(mWindow, &processId);
if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
{
return;
}
SetLastError(0); SetLastError(0);
LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc)); LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) { if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
{
mWindowSubclassed = false; mWindowSubclassed = false;
return; return;
} }
...@@ -282,7 +295,9 @@ void Surface::subclassWindow() ...@@ -282,7 +295,9 @@ void Surface::subclassWindow()
void Surface::unsubclassWindow() void Surface::unsubclassWindow()
{ {
if(!mWindowSubclassed) if(!mWindowSubclassed)
{
return; return;
}
// un-subclass // un-subclass
LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc)); LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
...@@ -292,7 +307,8 @@ void Surface::unsubclassWindow() ...@@ -292,7 +307,8 @@ void Surface::unsubclassWindow()
// hwnd as well and did not unsubclass before destroying its EGL context. The // hwnd as well and did not unsubclass before destroying its EGL context. The
// application should be modified to either subclass before initializing the // application should be modified to either subclass before initializing the
// EGL context, or to unsubclass before destroying the EGL context. // EGL context, or to unsubclass before destroying the EGL context.
if(parentWndFunc) { if(parentWndFunc)
{
LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc); LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc)); ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
} }
......
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