summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp87
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h4
-rw-r--r--src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch157
3 files changed, 248 insertions, 0 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
index 3d27548504..f567f47525 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -61,16 +61,19 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
mDepthStencilFormat(config->depthStencilFormat),
mSwapChain(nullptr),
mSwapIntervalDirty(true),
+ mWindowSubclassed(false),
mNativeWindow(window, config, directComposition == EGL_TRUE),
mWidth(width),
mHeight(height),
mSwapInterval(1),
mShareHandle(reinterpret_cast<HANDLE *>(shareHandle))
{
+ subclassWindow();
}
SurfaceD3D::~SurfaceD3D()
{
+ unsubclassWindow();
releaseSwapChain();
}
@@ -243,6 +246,90 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
return egl::Error(EGL_SUCCESS);
}
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+#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)
+ {
+ SurfaceD3D* surf = reinterpret_cast<SurfaceD3D*>(GetProp(hwnd, kSurfaceProperty));
+ if(surf)
+ {
+ surf->checkForOutOfDateSwapChain();
+ }
+ }
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+}
+#endif
+
+void SurfaceD3D::subclassWindow()
+{
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
+ {
+ return;
+ }
+
+ DWORD processId;
+ DWORD threadId = GetWindowThreadProcessId(window, &processId);
+ if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
+ {
+ return;
+ }
+
+ SetLastError(0);
+ LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
+ {
+ mWindowSubclassed = false;
+ return;
+ }
+
+ SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
+#endif
+}
+
+void SurfaceD3D::unsubclassWindow()
+{
+ if (!mWindowSubclassed)
+ {
+ return;
+ }
+
+#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
+ HWND window = mNativeWindow.getNativeWindow();
+ if (!window)
+ {
+ return;
+ }
+
+ // un-subclass
+ LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, 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_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
+ UNUSED_ASSERTION_VARIABLE(prevWndFunc);
+ ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
+ }
+
+ RemoveProp(window, kSurfaceProperty);
+ RemoveProp(window, kParentWndProc);
+#endif
+ mWindowSubclassed = false;
+}
+
bool SurfaceD3D::checkForOutOfDateSwapChain()
{
RECT client;
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
index b925bfc8cc..67d408ddd9 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
@@ -82,6 +82,9 @@ class SurfaceD3D : public SurfaceImpl
egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
+ void subclassWindow();
+ void unsubclassWindow();
+
RendererD3D *mRenderer;
egl::Display *mDisplay;
@@ -93,6 +96,7 @@ class SurfaceD3D : public SurfaceImpl
SwapChainD3D *mSwapChain;
bool mSwapIntervalDirty;
+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
EGLint mWidth;
diff --git a/src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch b/src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch
new file mode 100644
index 0000000000..e389219976
--- /dev/null
+++ b/src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch
@@ -0,0 +1,157 @@
+From 0a6fe2a93f451997d01e5e326846e0911d22622b Mon Sep 17 00:00:00 2001
+From: Oliver Wolff <oliver.wolff@qt.io>
+Date: Wed, 31 May 2017 15:50:28 +0200
+Subject: [PATCH] ANGLE: Fix flickering on resize when D3D9 is used
+
+By reverting ANGLE change d3b84ab51db09de238459b0dff2e8420c09aabf3
+we get rid of the flickering that happens on resize when D3D9 is
+used. The issue that was fixed there is not relevant in Qt's
+context so it is safe to revert the change.
+
+Task-number: QTBUG-59893
+Change-Id: I9306314b892612fbd1f7a058a2e606aedc0367bb
+---
+ .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 87 ++++++++++++++++++++++
+ .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.h | 4 +
+ 2 files changed, 91 insertions(+)
+
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+index 3d27548..f567f47 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
+@@ -61,16 +61,19 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer,
+ mDepthStencilFormat(config->depthStencilFormat),
+ mSwapChain(nullptr),
+ mSwapIntervalDirty(true),
++ mWindowSubclassed(false),
+ mNativeWindow(window, config, directComposition == EGL_TRUE),
+ mWidth(width),
+ mHeight(height),
+ mSwapInterval(1),
+ mShareHandle(reinterpret_cast<HANDLE *>(shareHandle))
+ {
++ subclassWindow();
+ }
+
+ SurfaceD3D::~SurfaceD3D()
+ {
++ unsubclassWindow();
+ releaseSwapChain();
+ }
+
+@@ -243,6 +246,90 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return egl::Error(EGL_SUCCESS);
+ }
+
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
++#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)
++ {
++ SurfaceD3D* surf = reinterpret_cast<SurfaceD3D*>(GetProp(hwnd, kSurfaceProperty));
++ if(surf)
++ {
++ surf->checkForOutOfDateSwapChain();
++ }
++ }
++ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
++ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
++}
++#endif
++
++void SurfaceD3D::subclassWindow()
++{
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
++ HWND window = mNativeWindow.getNativeWindow();
++ if (!window)
++ {
++ return;
++ }
++
++ DWORD processId;
++ DWORD threadId = GetWindowThreadProcessId(window, &processId);
++ if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId())
++ {
++ return;
++ }
++
++ SetLastError(0);
++ LONG_PTR oldWndProc = SetWindowLongPtr(window, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
++ if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS)
++ {
++ mWindowSubclassed = false;
++ return;
++ }
++
++ SetProp(window, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
++ SetProp(window, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
++ mWindowSubclassed = true;
++#endif
++}
++
++void SurfaceD3D::unsubclassWindow()
++{
++ if (!mWindowSubclassed)
++ {
++ return;
++ }
++
++#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
++ HWND window = mNativeWindow.getNativeWindow();
++ if (!window)
++ {
++ return;
++ }
++
++ // un-subclass
++ LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(window, 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_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc);
++ UNUSED_ASSERTION_VARIABLE(prevWndFunc);
++ ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc));
++ }
++
++ RemoveProp(window, kSurfaceProperty);
++ RemoveProp(window, kParentWndProc);
++#endif
++ mWindowSubclassed = false;
++}
++
+ bool SurfaceD3D::checkForOutOfDateSwapChain()
+ {
+ RECT client;
+diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
+index b925bfc..67d408d 100644
+--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h
+@@ -82,6 +82,9 @@ class SurfaceD3D : public SurfaceImpl
+ egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
+ egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
+
++ void subclassWindow();
++ void unsubclassWindow();
++
+ RendererD3D *mRenderer;
+ egl::Display *mDisplay;
+
+@@ -93,6 +96,7 @@ class SurfaceD3D : public SurfaceImpl
+
+ SwapChainD3D *mSwapChain;
+ bool mSwapIntervalDirty;
++ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+
+ NativeWindow mNativeWindow; // Handler for the Window that the surface is created for.
+ EGLint mWidth;
+--
+2.10.2.windows.1
+