From 916cfede0536ce63a1a5851bc675f5082e3c641c Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Sun, 3 May 2015 20:56:04 +0300 Subject: ANGLE: Allow Windows Phone to communicate swap region eglPostSubBufferNV is used to communicate the size of the window, as otherwise there is no way for the renderer to know if the last frame was rendered in landscape or portrait, causing rendering glitches when the orientation changes. The rotation flags are utilized in a few additional places now to fix some corner cases where the rotation was not applied. This patch should be squashed into "ANGLE-Improve-Windows-Phone-Support" during the next ANGLE rebase. Task-number: QTBUG-44333 Task-number: QTBUG-43502 Change-Id: Iec37f7531854184819c30c87eab82d96d56ff133 Reviewed-by: Oliver Wolff --- .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 2 + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 28 ++-- .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 5 +- .../angle/src/libGLESv2/entry_points_egl_ext.cpp | 2 + ...-Windows-Phone-to-communicate-swap-region.patch | 145 +++++++++++++++++++++ 5 files changed, 169 insertions(+), 13 deletions(-) create mode 100644 src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch (limited to 'src') diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp index 4fde295443..4a87488014 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp @@ -189,6 +189,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return egl::Error(EGL_SUCCESS); } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here if (x + width > mWidth) { width = mWidth - x; @@ -198,6 +199,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { height = mHeight - y; } +#endif if (width == 0 || height == 0) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index 298f3ccbd2..dc539cf66e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -552,18 +552,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); +#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Create a quad in homogeneous coordinates - float x1 = (x / float(mWidth)) * 2.0f - 1.0f; - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + float x1 = -1.0f; + float y1 = -1.0f; + float x2 = 1.0f; + float y2 = 1.0f; -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) const float dim = std::max(mWidth, mHeight); - float u1 = x / dim; - float v1 = y / dim; - float u2 = (x + width) / dim; - float v2 = (y + height) / dim; + float u1 = 0; + float v1 = 0; + float u2 = float(width) / dim; + float v2 = float(height) / dim; const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); const bool rotateL = flags == NativeWindow::RotateLeft; @@ -573,6 +573,12 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); #else + // Create a quad in homogeneous coordinates + float x1 = (x / float(mWidth)) * 2.0f - 1.0f; + float y1 = (y / float(mHeight)) * 2.0f - 1.0f; + float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; + float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + float u1 = x / float(mWidth); float v1 = y / float(mHeight); float u2 = (x + width) / float(mWidth); @@ -613,8 +619,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) viewport.TopLeftX = 0; viewport.TopLeftY = 0; #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; - viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; + viewport.Width = (rotateL || rotateR) ? height : width; + viewport.Height = (rotateL || rotateR) ? width : height; #else viewport.Width = mWidth; viewport.Height = mHeight; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp index 350526c867..fa9a69c5a1 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp @@ -100,6 +100,7 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() if (SUCCEEDED(result)) { result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); + orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); } #endif @@ -135,8 +136,8 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor } DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; - swapChainDesc.Width = width; - swapChainDesc.Height = height; + swapChainDesc.Width = mRotationFlags ? height : width; + swapChainDesc.Height = mRotationFlags ? width : height; swapChainDesc.Format = format; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp index ded73dbb48..62f3ca1207 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp @@ -101,12 +101,14 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin return EGL_FALSE; } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround if (!display->getExtensions().postSubBuffer) { // Spec is not clear about how this should be handled. SetGlobalError(Error(EGL_SUCCESS)); return EGL_TRUE; } +#endif error = eglSurface->postSubBuffer(x, y, width, height); if (error.isError()) diff --git a/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch b/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch new file mode 100644 index 0000000000..5c6ef7b036 --- /dev/null +++ b/src/angle/patches/0006-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch @@ -0,0 +1,145 @@ +From f0fb8d75bd2c7a894df1cb7e7d3dcd1ad0fd88d0 Mon Sep 17 00:00:00 2001 +From: Andrew Knight +Date: Sun, 3 May 2015 20:55:04 +0300 +Subject: [PATCH] ANGLE: Allow Windows Phone to communicate swap region + +eglPostSubBufferNV is used to communicate the size of the window, as +otherwise there is no way for the renderer to know if the last frame was +rendered in landscape or portrait, causing rendering glitches when the +orientation changes. The rotation flags are utilized in a few additional +places now to fix some corner cases where the rotation was not applied. + +This patch should be squashed into "ANGLE-Improve-Windows-Phone-Support" +during the next ANGLE rebase. + +Task-number: QTBUG-44333 +Task-number: QTBUG-43502 +Change-Id: Iec37f7531854184819c30c87eab82d96d56ff133 +--- + .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 2 ++ + .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 28 +++++++++++++--------- + .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 5 ++-- + .../angle/src/libGLESv2/entry_points_egl_ext.cpp | 2 ++ + 4 files changed, 24 insertions(+), 13 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +index 4fde295..4a87488 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +@@ -189,6 +189,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + return egl::Error(EGL_SUCCESS); + } + ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here + if (x + width > mWidth) + { + width = mWidth - x; +@@ -198,6 +199,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + { + height = mHeight - y; + } ++#endif + + if (width == 0 || height == 0) + { +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +index 298f3cc..dc539cf 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +@@ -552,18 +552,18 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + ++#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + // Create a quad in homogeneous coordinates +- float x1 = (x / float(mWidth)) * 2.0f - 1.0f; +- float y1 = (y / float(mHeight)) * 2.0f - 1.0f; +- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; +- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; ++ float x1 = -1.0f; ++ float y1 = -1.0f; ++ float x2 = 1.0f; ++ float y2 = 1.0f; + +-#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + const float dim = std::max(mWidth, mHeight); +- float u1 = x / dim; +- float v1 = y / dim; +- float u2 = (x + width) / dim; +- float v2 = (y + height) / dim; ++ float u1 = 0; ++ float v1 = 0; ++ float u2 = float(width) / dim; ++ float v2 = float(height) / dim; + + const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); + const bool rotateL = flags == NativeWindow::RotateLeft; +@@ -573,6 +573,12 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); + #else ++ // Create a quad in homogeneous coordinates ++ float x1 = (x / float(mWidth)) * 2.0f - 1.0f; ++ float y1 = (y / float(mHeight)) * 2.0f - 1.0f; ++ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; ++ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; ++ + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); +@@ -613,8 +619,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +- viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; +- viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; ++ viewport.Width = (rotateL || rotateR) ? height : width; ++ viewport.Height = (rotateL || rotateR) ? width : height; + #else + viewport.Width = mWidth; + viewport.Height = mHeight; +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +index 350526c..fa9a69c 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +@@ -100,6 +100,7 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() + if (SUCCEEDED(result)) + { + result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); ++ orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); + } + #endif + +@@ -135,8 +136,8 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactor + } + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; +- swapChainDesc.Width = width; +- swapChainDesc.Height = height; ++ swapChainDesc.Width = mRotationFlags ? height : width; ++ swapChainDesc.Height = mRotationFlags ? width : height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; +diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +index ded73db..62f3ca1 100644 +--- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp ++++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +@@ -101,12 +101,14 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin + return EGL_FALSE; + } + ++#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround + if (!display->getExtensions().postSubBuffer) + { + // Spec is not clear about how this should be handled. + SetGlobalError(Error(EGL_SUCCESS)); + return EGL_TRUE; + } ++#endif + + error = eglSurface->postSubBuffer(x, y, width, height); + if (error.isError()) +-- +1.9.5.msysgit.0 + -- cgit v1.2.3