From 7ff7dd46f54e23ae309887366bf477de9c33005b Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Wed, 17 Sep 2014 00:58:29 +0300 Subject: [PATCH 09/16] ANGLE: Support WinRT This enables EGL for WinRT's native types, and adjusts some codepaths to accommodate differences between desktop Windows and WinRT. - WinRT native handles added to eglplatform.h - References to native handles in libEGL/libGLESv2 follow eglplatform.h - D3D 11.1 structures and methods used when necessary - TLS replaced with thread attribute - LocalAlloc/Free replaced with Heap API Change-Id: Ia90377e700d335a1c569c2145008dd4b0dfd84d3 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/include/EGL/eglplatform.h | 10 +- src/3rdparty/angle/src/common/platform.h | 3 + src/3rdparty/angle/src/common/tls.cpp | 37 ++++- src/3rdparty/angle/src/common/tls.h | 6 +- src/3rdparty/angle/src/common/utilities.cpp | 51 +++++- src/3rdparty/angle/src/libEGL/Display.cpp | 13 +- src/3rdparty/angle/src/libEGL/Display.h | 6 +- src/3rdparty/angle/src/libEGL/Surface.cpp | 185 ++++++++++++++++++++- src/3rdparty/angle/src/libEGL/Surface.h | 37 ++++- src/3rdparty/angle/src/libEGL/libEGL.cpp | 8 +- src/3rdparty/angle/src/libEGL/main.cpp | 21 +++ src/3rdparty/angle/src/libGLESv2/main.cpp | 20 +++ src/3rdparty/angle/src/libGLESv2/main.h | 4 + .../angle/src/libGLESv2/renderer/Renderer.h | 2 +- .../angle/src/libGLESv2/renderer/SwapChain.h | 15 +- .../src/libGLESv2/renderer/d3d/HLSLCompiler.cpp | 11 +- .../libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 13 +- .../src/libGLESv2/renderer/d3d/d3d11/Renderer11.h | 4 +- .../libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp | 73 ++++++-- .../src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h | 6 +- .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp | 2 +- .../src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h | 2 +- 22 files changed, 481 insertions(+), 48 deletions(-) diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h index 3ab8844..ea9f577 100644 --- a/src/3rdparty/angle/include/EGL/eglplatform.h +++ b/src/3rdparty/angle/include/EGL/eglplatform.h @@ -67,7 +67,15 @@ * implementations. */ -#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */ + +struct IUnknown; + +typedef IUnknown *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef IUnknown *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index d07297d..387ba41 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -11,6 +11,9 @@ #if defined(_WIN32) || defined(_WIN64) # define ANGLE_PLATFORM_WINDOWS 1 +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) +# define ANGLE_PLATFORM_WINRT 1 +# endif #elif defined(__APPLE__) # define ANGLE_PLATFORM_APPLE 1 # define ANGLE_PLATFORM_POSIX 1 diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp index 6b78219..c46fab5 100644 --- a/src/3rdparty/angle/src/common/tls.cpp +++ b/src/3rdparty/angle/src/common/tls.cpp @@ -10,11 +10,28 @@ #include +#if defined(ANGLE_PLATFORM_WINRT) +#include +std::vector *tls = nullptr; +std::vector *freeIndices = nullptr; +#endif + TLSIndex CreateTLSIndex() { TLSIndex index; -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + if (!tls) + tls = new std::vector; + if (freeIndices && !freeIndices->empty()) { + index = freeIndices->back(); + freeIndices->pop_back(); + return index; + } else { + tls->push_back(nullptr); + return tls->size() - 1; + } +#elif defined(ANGLE_PLATFORM_WINDOWS) index = TlsAlloc(); #elif defined(ANGLE_PLATFORM_POSIX) // Create global pool key @@ -36,7 +53,12 @@ bool DestroyTLSIndex(TLSIndex index) return false; } -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + if (!freeIndices) + freeIndices = new std::vector; + freeIndices->push_back(index); + return true; +#elif ANGLE_PLATFORM_WINDOWS return (TlsFree(index) == TRUE); #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_key_delete(index) == 0); @@ -51,7 +73,10 @@ bool SetTLSValue(TLSIndex index, void *value) return false; } -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + tls->at(index) = value; + return true; +#elif defined(ANGLE_PLATFORM_WINDOWS) return (TlsSetValue(index, value) == TRUE); #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_setspecific(index, value) == 0); @@ -60,13 +85,17 @@ bool SetTLSValue(TLSIndex index, void *value) void *GetTLSValue(TLSIndex index) { +#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index"); +#endif if (index == TLS_INVALID_INDEX) { return NULL; } -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + return tls->at(index); +#elif defined(ANGLE_PLATFORM_WINDOWS) return TlsGetValue(index); #elif defined(ANGLE_PLATFORM_POSIX) return pthread_getspecific(index); diff --git a/src/3rdparty/angle/src/common/tls.h b/src/3rdparty/angle/src/common/tls.h index 4b25fbc..c40ae1a 100644 --- a/src/3rdparty/angle/src/common/tls.h +++ b/src/3rdparty/angle/src/common/tls.h @@ -11,7 +11,11 @@ #include "common/platform.h" -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + typedef size_t TLSIndex; +# define TLS_OUT_OF_INDEXES (static_cast(-1)) +# define TLS_INVALID_INDEX TLS_OUT_OF_INDEXES +#elif defined(ANGLE_PLATFORM_WINDOWS) typedef DWORD TLSIndex; # define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES) #elif defined(ANGLE_PLATFORM_POSIX) diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp index 405f119..4b8e325 100644 --- a/src/3rdparty/angle/src/common/utilities.cpp +++ b/src/3rdparty/angle/src/common/utilities.cpp @@ -9,6 +9,14 @@ #include "common/utilities.h" #include "common/mathutil.h" #include "common/platform.h" +#if defined(ANGLE_PLATFORM_WINRT) +# include +# include +# include +# include + using namespace Microsoft::WRL; + using namespace ABI::Windows::Storage; +#endif #include @@ -441,7 +449,48 @@ int VariableSortOrder(GLenum type) std::string getTempPath() { -#ifdef ANGLE_PLATFORM_WINDOWS +#if defined(ANGLE_PLATFORM_WINRT) + static std::string path; + + while (path.empty()) + { + ComPtr factory; + Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData); + HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory)); + if (FAILED(result)) + break; + + ComPtr applicationData; + result = factory->get_Current(&applicationData); + if (FAILED(result)) + break; + + ComPtr storageFolder; + result = applicationData->get_LocalFolder(&storageFolder); + if (FAILED(result)) + break; + + ComPtr localFolder; + result = storageFolder.As(&localFolder); + if (FAILED(result)) + break; + + HSTRING localFolderPath; + result = localFolder->get_Path(&localFolderPath); + if (FAILED(result)) + break; + + std::wstring_convert< std::codecvt_utf8 > converter; + path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL)); + if (path.empty()) + { + UNREACHABLE(); + break; + } + } + + return path; +#elif defined(ANGLE_PLATFORM_WINDOWS) char path[MAX_PATH]; DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); if (pathLen == 0) diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp index aaebdb3..ba09631 100644 --- a/src/3rdparty/angle/src/libEGL/Display.cpp +++ b/src/3rdparty/angle/src/libEGL/Display.cpp @@ -56,6 +56,10 @@ Display::Display(EGLNativeDisplayType displayId, EGLint displayType) mRequestedDisplayType(displayType), mRenderer(NULL) { +#if defined(ANGLE_PLATFORM_WINRT) + if (mDisplayId) + mDisplayId->AddRef(); +#endif } Display::~Display() @@ -68,6 +72,11 @@ Display::~Display() { displays->erase(iter); } + +#if defined(ANGLE_PLATFORM_WINRT) + if (mDisplayId) + mDisplayId->Release(); +#endif } bool Display::initialize() @@ -192,7 +201,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) -EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList) +EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList) { const Config *configuration = mConfigSet.get(config); EGLint postSubBufferSupported = EGL_FALSE; @@ -493,7 +502,7 @@ bool Display::isValidSurface(egl::Surface *surface) return mSurfaceSet.find(surface) != mSurfaceSet.end(); } -bool Display::hasExistingWindowSurface(HWND window) +bool Display::hasExistingWindowSurface(EGLNativeWindowType window) { for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) { diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h index 250878f..73ba767 100644 --- a/src/3rdparty/angle/src/libEGL/Display.h +++ b/src/3rdparty/angle/src/libEGL/Display.h @@ -43,7 +43,7 @@ class Display bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); - EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList); + EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList); EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList); EGLContext createContext(EGLConfig configHandle, EGLint clientVersion, const gl::Context *shareContext, bool notifyResets, bool robustAccess); @@ -54,7 +54,7 @@ class Display bool isValidConfig(EGLConfig config); bool isValidContext(gl::Context *context); bool isValidSurface(egl::Surface *surface); - bool hasExistingWindowSurface(HWND window); + bool hasExistingWindowSurface(EGLNativeWindowType window); rx::Renderer *getRenderer() { return mRenderer; }; @@ -65,6 +65,8 @@ class Display const char *getExtensionString() const; const char *getVendorString() const; + EGLNativeDisplayType getDisplayId() const { return mDisplayId; } + private: DISALLOW_COPY_AND_ASSIGN(Display); diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp index 13b0f20..fa79961 100644 --- a/src/3rdparty/angle/src/libEGL/Surface.cpp +++ b/src/3rdparty/angle/src/libEGL/Surface.cpp @@ -22,10 +22,20 @@ #include "libEGL/main.h" #include "libEGL/Display.h" +#if defined(ANGLE_PLATFORM_WINRT) +# include "wrl.h" +# include "windows.graphics.display.h" +# include "windows.ui.core.h" +using namespace ABI::Windows::Graphics::Display; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::UI::Core; +using namespace Microsoft::WRL; +#endif + namespace egl { -Surface::Surface(Display *display, const Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) +Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported) : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) { mRenderer = mDisplay->getRenderer(); @@ -43,6 +53,17 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint fix mHeight = height; setSwapInterval(1); mFixedSize = fixedSize; + mSwapFlags = rx::SWAP_NORMAL; +#if defined(ANGLE_PLATFORM_WINRT) + if (mWindow) + mWindow->AddRef(); + mScaleFactor = 1.0; + mSizeToken.value = 0; + mDpiToken.value = 0; +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + mOrientationToken.value = 0; +# endif +#endif subclassWindow(); } @@ -64,16 +85,86 @@ Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGL setSwapInterval(1); // This constructor is for offscreen surfaces, which are always fixed-size. mFixedSize = EGL_TRUE; + mSwapFlags = rx::SWAP_NORMAL; +#if defined(ANGLE_PLATFORM_WINRT) + mScaleFactor = 1.0; + mSizeToken.value = 0; + mDpiToken.value = 0; +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + mOrientationToken.value = 0; +# endif +#endif } Surface::~Surface() { +#if defined(ANGLE_PLATFORM_WINRT) + if (mSizeToken.value) { + ComPtr coreWindow; + HRESULT hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + + hr = coreWindow->remove_SizeChanged(mSizeToken); + ASSERT(SUCCEEDED(hr)); + } + if (mDpiToken.value) { + ComPtr displayInformation; + HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + + hr = displayInformation->remove_DpiChanged(mDpiToken); + ASSERT(SUCCEEDED(hr)); + } +# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + if (mOrientationToken.value) { + ComPtr displayInformation; + HRESULT hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + + hr = displayInformation->remove_OrientationChanged(mOrientationToken); + ASSERT(SUCCEEDED(hr)); + } +# endif +#endif unsubclassWindow(); release(); } bool Surface::initialize() { +#if defined(ANGLE_PLATFORM_WINRT) + if (!mFixedSize) { + HRESULT hr; + ComPtr displayInformation; + hr = mDisplay->getDisplayId()->QueryInterface(displayInformation.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + onDpiChanged(displayInformation.Get(), 0); + hr = displayInformation->add_DpiChanged(Callback>(this, &Surface::onDpiChanged).Get(), + &mDpiToken); + ASSERT(SUCCEEDED(hr)); + +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + onOrientationChanged(displayInformation.Get(), 0); + hr = displayInformation->add_OrientationChanged(Callback>(this, &Surface::onOrientationChanged).Get(), + &mOrientationToken); + ASSERT(SUCCEEDED(hr)); +# endif + + ComPtr coreWindow; + hr = mWindow->QueryInterface(coreWindow.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + + Rect rect; + hr = coreWindow->get_Bounds(&rect); + ASSERT(SUCCEEDED(hr)); + mWidth = rect.Width * mScaleFactor; + mHeight = rect.Height * mScaleFactor; + hr = coreWindow->add_SizeChanged(Callback>(this, &Surface::onSizeChanged).Get(), + &mSizeToken); + ASSERT(SUCCEEDED(hr)); + } +#endif + if (!resetSwapChain()) return false; @@ -90,6 +181,11 @@ void Surface::release() mTexture->releaseTexImage(); mTexture = NULL; } + +#if defined(ANGLE_PLATFORM_WINRT) + if (mWindow) + mWindow->Release(); +#endif } bool Surface::resetSwapChain() @@ -99,6 +195,7 @@ bool Surface::resetSwapChain() int width; int height; +#if !defined(ANGLE_PLATFORM_WINRT) if (!mFixedSize) { RECT windowRect; @@ -114,6 +211,7 @@ bool Surface::resetSwapChain() height = windowRect.bottom - windowRect.top; } else +#endif { // non-window surface - size is determined at creation width = mWidth; @@ -207,7 +305,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return true; } - EGLint status = mSwapChain->swapRect(x, y, width, height); + EGLint status = mSwapChain->swapRect(x, y, width, height, mSwapFlags); if (status == EGL_CONTEXT_LOST) { @@ -224,7 +322,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return true; } -HWND Surface::getWindowHandle() +EGLNativeWindowType Surface::getWindowHandle() { return mWindow; } @@ -233,6 +331,7 @@ HWND Surface::getWindowHandle() #define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") +#if !defined(ANGLE_PLATFORM_WINRT) static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { if (message == WM_SIZE) @@ -246,9 +345,11 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); } +#endif void Surface::subclassWindow() { +#if !defined(ANGLE_PLATFORM_WINRT) if (!mWindow) { return; @@ -272,10 +373,14 @@ void Surface::subclassWindow() SetProp(mWindow, kSurfaceProperty, reinterpret_cast(this)); SetProp(mWindow, kParentWndProc, reinterpret_cast(oldWndProc)); mWindowSubclassed = true; +#else + mWindowSubclassed = false; +#endif } void Surface::unsubclassWindow() { +#if !defined(ANGLE_PLATFORM_WINRT) if(!mWindowSubclassed) { return; @@ -299,16 +404,18 @@ void Surface::unsubclassWindow() RemoveProp(mWindow, kSurfaceProperty); RemoveProp(mWindow, kParentWndProc); mWindowSubclassed = false; +#endif } bool Surface::checkForOutOfDateSwapChain() { - RECT client; int clientWidth = getWidth(); int clientHeight = getHeight(); bool sizeDirty = false; +#if !defined(ANGLE_PLATFORM_WINRT) if (!mFixedSize && !IsIconic(getWindowHandle())) { + RECT client; // The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized // because that's not a useful size to render to. if (!GetClientRect(getWindowHandle(), &client)) @@ -322,6 +429,7 @@ bool Surface::checkForOutOfDateSwapChain() clientHeight = client.bottom - client.top; sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); } +#endif bool wasDirty = (mSwapIntervalDirty || sizeDirty); @@ -446,4 +554,73 @@ EGLenum Surface::getFormat() const { return mConfig->mRenderTargetFormat; } + +#if defined(ANGLE_PLATFORM_WINRT) + +HRESULT Surface::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *args) +{ + HRESULT hr; + Size size; + hr = args->get_Size(&size); + ASSERT(SUCCEEDED(hr)); + + resizeSwapChain(std::floor(size.Width * mScaleFactor + 0.5), + std::floor(size.Height * mScaleFactor + 0.5)); + + if (static_cast(getCurrentDrawSurface()) == this) + { + glMakeCurrent(glGetCurrentContext(), static_cast(getCurrentDisplay()), this); + } + + return S_OK; +} + +HRESULT Surface::onDpiChanged(IDisplayInformation *displayInformation, IInspectable *) +{ + HRESULT hr; +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + ComPtr displayInformation2; + hr = displayInformation->QueryInterface(displayInformation2.GetAddressOf()); + ASSERT(SUCCEEDED(hr)); + + hr = displayInformation2->get_RawPixelsPerViewPixel(&mScaleFactor); + ASSERT(SUCCEEDED(hr)); +# else + ResolutionScale resolutionScale; + hr = displayInformation->get_ResolutionScale(&resolutionScale); + ASSERT(SUCCEEDED(hr)); + + mScaleFactor = double(resolutionScale) / 100.0; +# endif + return S_OK; +} + +# if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +HRESULT Surface::onOrientationChanged(IDisplayInformation *displayInformation, IInspectable *) +{ + HRESULT hr; + DisplayOrientations orientation; + hr = displayInformation->get_CurrentOrientation(&orientation); + ASSERT(SUCCEEDED(hr)); + switch (orientation) { + default: + case DisplayOrientations_Portrait: + mSwapFlags = rx::SWAP_NORMAL; + break; + case DisplayOrientations_Landscape: + mSwapFlags = rx::SWAP_ROTATE_90; + break; + case DisplayOrientations_LandscapeFlipped: + mSwapFlags = rx::SWAP_ROTATE_270; + break; + case DisplayOrientations_PortraitFlipped: + mSwapFlags = rx::SWAP_ROTATE_180; + break; + } + return S_OK; +} +# endif + +#endif + } diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h index 24c66b7..ebffce8fe 100644 --- a/src/3rdparty/angle/src/libEGL/Surface.h +++ b/src/3rdparty/angle/src/libEGL/Surface.h @@ -15,6 +15,20 @@ #include "common/angleutils.h" +#if defined(ANGLE_PLATFORM_WINRT) +#include +namespace ABI { namespace Windows { + namespace UI { namespace Core { + struct ICoreWindow; + struct IWindowSizeChangedEventArgs; + } } + namespace Graphics { namespace Display { + struct IDisplayInformation; + } } +} } +struct IInspectable; +#endif + namespace gl { class Texture2D; @@ -33,7 +47,7 @@ class Config; class Surface { public: - Surface(Display *display, const egl::Config *config, HWND window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported); + Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported); Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget); virtual ~Surface(); @@ -42,7 +56,7 @@ class Surface void release(); bool resetSwapChain(); - HWND getWindowHandle(); + EGLNativeWindowType getWindowHandle(); bool swap(); bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); @@ -71,6 +85,14 @@ class Surface private: DISALLOW_COPY_AND_ASSIGN(Surface); +#if defined(ANGLE_PLATFORM_WINRT) + HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); + HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); +# endif +#endif + Display *const mDisplay; rx::Renderer *mRenderer; @@ -83,7 +105,7 @@ private: bool resetSwapChain(int backbufferWidth, int backbufferHeight); bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - const HWND mWindow; // Window that the surface is created for. + const EGLNativeWindowType mWindow; // Window that the surface is created for. bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking const egl::Config *mConfig; // EGL config surface was created with EGLint mHeight; // Height of surface @@ -104,9 +126,18 @@ private: EGLint mSwapInterval; EGLint mPostSubBufferSupported; EGLint mFixedSize; + EGLint mSwapFlags; bool mSwapIntervalDirty; gl::Texture2D *mTexture; +#if defined(ANGLE_PLATFORM_WINRT) + double mScaleFactor; + EventRegistrationToken mSizeToken; + EventRegistrationToken mDpiToken; +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + EventRegistrationToken mOrientationToken; +# endif +#endif }; } diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp index 7ce2b93..7ea11c5 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.cpp +++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp @@ -13,6 +13,7 @@ #include "common/debug.h" #include "common/version.h" +#include "common/platform.h" #include "libGLESv2/Context.h" #include "libGLESv2/Texture.h" #include "libGLESv2/main.h" @@ -120,12 +121,13 @@ EGLDisplay __stdcall eglGetPlatformDisplayEXT(EGLenum platform, void *native_dis } EGLNativeDisplayType displayId = static_cast(native_display); - +#if !defined(ANGLE_PLATFORM_WINRT) // Validate the display device context if (WindowFromDC(displayId) == NULL) { return egl::success(EGL_NO_DISPLAY); } +#endif EGLint requestedDisplayType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; if (attrib_list) @@ -327,14 +329,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG return EGL_NO_SURFACE; } +#if !defined(ANGLE_PLATFORM_WINRT) HWND window = (HWND)win; if (!IsWindow(window)) { return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } +#endif - return display->createWindowSurface(window, config, attrib_list); + return display->createWindowSurface(win, config, attrib_list); } EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp index 8a1baef..e74737e 100644 --- a/src/3rdparty/angle/src/libEGL/main.cpp +++ b/src/3rdparty/angle/src/libEGL/main.cpp @@ -11,6 +11,9 @@ #include "common/debug.h" #include "common/tls.h" +#if defined(ANGLE_PLATFORM_WINRT) +__declspec(thread) +#endif static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; namespace egl @@ -18,6 +21,12 @@ namespace egl Current *AllocateCurrent() { +#if defined(ANGLE_PLATFORM_WINRT) + if (currentTLS == TLS_OUT_OF_INDEXES) + { + currentTLS = CreateTLSIndex(); + } +#endif ASSERT(currentTLS != TLS_OUT_OF_INDEXES); if (currentTLS == TLS_OUT_OF_INDEXES) { @@ -42,6 +51,12 @@ Current *AllocateCurrent() void DeallocateCurrent() { +#if defined(ANGLE_PLATFORM_WINRT) + if (currentTLS == TLS_OUT_OF_INDEXES) + { + return; + } +#endif Current *current = reinterpret_cast(GetTLSValue(currentTLS)); SafeDelete(current); SetTLSValue(currentTLS, NULL); @@ -72,6 +87,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved } #endif +#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain + return DisableThreadLibraryCalls(instance); +#endif + currentTLS = CreateTLSIndex(); if (currentTLS == TLS_OUT_OF_INDEXES) { @@ -86,7 +105,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved break; case DLL_THREAD_DETACH: { +#if !defined(ANGLE_PLATFORM_WINRT) egl::DeallocateCurrent(); +#endif } break; case DLL_PROCESS_DETACH: diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp index 1c577bc..51447e2 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp @@ -11,6 +11,9 @@ #include "common/tls.h" +#if defined(ANGLE_PLATFORM_WINRT) +__declspec(thread) +#endif static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; namespace gl @@ -18,6 +21,12 @@ namespace gl Current *AllocateCurrent() { +#if defined(ANGLE_PLATFORM_WINRT) + if (currentTLS == TLS_OUT_OF_INDEXES) + { + currentTLS = CreateTLSIndex(); + } +#endif ASSERT(currentTLS != TLS_OUT_OF_INDEXES); if (currentTLS == TLS_OUT_OF_INDEXES) { @@ -39,6 +48,12 @@ Current *AllocateCurrent() void DeallocateCurrent() { +#if defined(ANGLE_PLATFORM_WINRT) + if (currentTLS == TLS_OUT_OF_INDEXES) + { + return; + } +#endif Current *current = reinterpret_cast(GetTLSValue(currentTLS)); SafeDelete(current); SetTLSValue(currentTLS, NULL); @@ -54,6 +69,9 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved { case DLL_PROCESS_ATTACH: { +#if defined(ANGLE_PLATFORM_WINRT) // On WinRT, don't handle TLS from DllMain + return DisableThreadLibraryCalls(instance); +#endif currentTLS = CreateTLSIndex(); if (currentTLS == TLS_OUT_OF_INDEXES) { @@ -73,8 +91,10 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved break; case DLL_PROCESS_DETACH: { +#if !defined(ANGLE_PLATFORM_WINRT) gl::DeallocateCurrent(); DestroyTLSIndex(currentTLS); +#endif } break; default: diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h index 684c302..c30ad33 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.h +++ b/src/3rdparty/angle/src/libGLESv2/main.h @@ -14,6 +14,10 @@ #include #include +#ifndef Sleep +#define Sleep(ms) WaitForSingleObjectEx(GetCurrentThread(), ms, FALSE) +#endif + namespace egl { class Display; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index 7adbea2..b224974 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -107,7 +107,7 @@ class Renderer virtual void sync(bool block) = 0; - virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; + virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0; virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h index 12be9b3..1ec702f 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h @@ -15,14 +15,23 @@ #include #include +#include namespace rx { +enum SwapFlags +{ + SWAP_NORMAL = 0, + SWAP_ROTATE_90 = 1, + SWAP_ROTATE_270 = 2, + SWAP_ROTATE_180 = SWAP_ROTATE_90|SWAP_ROTATE_270, +}; + class SwapChain { public: - SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) + SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat) { } @@ -31,13 +40,13 @@ class SwapChain virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) = 0; virtual void recreate() = 0; virtual HANDLE getShareHandle() {return mShareHandle;}; protected: - const HWND mWindow; // Window that the surface is created for. + const EGLNativeWindowType mWindow; // Window that the surface is created for. const GLenum mBackBufferFormat; const GLenum mDepthBufferFormat; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp index 5715d5f..d013197 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/HLSLCompiler.cpp @@ -9,6 +9,7 @@ #include "libGLESv2/main.h" #include "common/utilities.h" +#include "common/platform.h" #if defined(__MINGW32__) && !defined(D3DCOMPILER_DLL) @@ -45,11 +46,7 @@ HLSLCompiler::~HLSLCompiler() bool HLSLCompiler::initialize() { -<<<<<<< HEAD - TRACE_EVENT0("gpu", "initializeCompiler"); -======= #if !defined(ANGLE_PLATFORM_WINRT) ->>>>>>> 429814a... ANGLE: remove event tracing #if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES) // Find a D3DCompiler module that had already been loaded based on a predefined list of versions. static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES; @@ -94,7 +91,9 @@ bool HLSLCompiler::initialize() mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); ASSERT(mD3DCompileFunc); - +#else + mD3DCompileFunc = reinterpret_cast(&D3DCompile); +#endif return mD3DCompileFunc != NULL; } @@ -111,7 +110,9 @@ void HLSLCompiler::release() ShaderBlob *HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, const UINT optimizationFlags[], const char *flagNames[], int attempts) const { +#if !defined(ANGLE_PLATFORM_WINRT) ASSERT(mD3DCompilerModule && mD3DCompileFunc); +#endif if (!hlsl) { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp index ed880c3..0bb7489 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp @@ -6,6 +6,7 @@ // Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. +#include "common/platform.h" #include "libGLESv2/main.h" #include "libGLESv2/Buffer.h" #include "libGLESv2/FramebufferAttachment.h" @@ -135,6 +136,7 @@ EGLint Renderer11::initialize() return EGL_NOT_INITIALIZED; } +#if !defined(ANGLE_PLATFORM_WINRT) mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); @@ -153,6 +155,7 @@ EGLint Renderer11::initialize() ERR("Could not retrieve D3D11CreateDevice address - aborting!\n"); return EGL_NOT_INITIALIZED; } +#endif D3D_FEATURE_LEVEL featureLevels[] = { @@ -207,7 +210,7 @@ EGLint Renderer11::initialize() } } -#if !ANGLE_SKIP_DXGI_1_2_CHECK +#if !ANGLE_SKIP_DXGI_1_2_CHECK && !defined(ANGLE_PLATFORM_WINRT) // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. // The easiest way to check is to query for a IDXGIDevice2. bool requireDXGI1_2 = false; @@ -237,8 +240,12 @@ EGLint Renderer11::initialize() } #endif +#if !defined(ANGLE_PLATFORM_WINRT) IDXGIDevice *dxgiDevice = NULL; - result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); +#else + IDXGIDevice1 *dxgiDevice = NULL; +#endif + result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); if (FAILED(result)) { @@ -408,7 +415,7 @@ void Renderer11::sync(bool block) } } -SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) { return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h index d309f14..b86f5e5 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.h @@ -57,7 +57,7 @@ class Renderer11 : public Renderer virtual void sync(bool block); - virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual gl::Error generateSwizzle(gl::Texture *texture); virtual gl::Error setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); @@ -222,7 +222,7 @@ class Renderer11 : public Renderer HMODULE mD3d11Module; HMODULE mDxgiModule; - HDC mDc; + EGLNativeDisplayType mDc; EGLint mRequestedDisplay; HLSLCompiler mCompiler; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp index 50dae4e..787c511 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.cpp @@ -6,6 +6,7 @@ // SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. +#include "common/platform.h" #include "libGLESv2/renderer/d3d/d3d11/SwapChain11.h" #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h" #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h" @@ -18,7 +19,7 @@ namespace rx { -SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, +SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) { @@ -38,6 +39,8 @@ SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, mPassThroughPS = NULL; mWidth = -1; mHeight = -1; + mViewportWidth = -1; + mViewportHeight = -1; mSwapInterval = 0; mAppCreatedShareHandle = mShareHandle != NULL; mPassThroughResourcesInit = false; @@ -92,6 +95,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei ASSERT(backbufferHeight >= 1); // Preserve the render target content +#if !defined(ANGLE_PLATFORM_WINRT) ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; if (previousOffscreenTexture) { @@ -99,6 +103,7 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei } const int previousWidth = mWidth; const int previousHeight = mHeight; +#endif releaseOffscreenTexture(); @@ -281,7 +286,12 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei mWidth = backbufferWidth; mHeight = backbufferHeight; +#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP + mViewportWidth = backbufferWidth; + mViewportHeight = backbufferHeight; +#endif +#if !defined(ANGLE_PLATFORM_WINRT) if (previousOffscreenTexture != NULL) { D3D11_BOX sourceBox = {0}; @@ -300,9 +310,10 @@ EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHei if (mSwapChain) { - swapRect(0, 0, mWidth, mHeight); + swapRect(0, 0, mWidth, mHeight, SWAP_NORMAL); } } +#endif return EGL_SUCCESS; } @@ -329,8 +340,15 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) SafeRelease(mBackBufferRTView); // Resize swap chain + HRESULT result; +#if !defined(ANGLE_PLATFORM_WINRT) || WINAPI_FAMILY==WINAPI_FAMILY_PC_APP // Windows phone swap chain is never resized, only the texture is +#if !defined(ANGLE_PLATFORM_WINRT) + const int bufferCount = 1; +#else + const int bufferCount = 2; +#endif const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mBackBufferFormat); - HRESULT result = mSwapChain->ResizeBuffers(1, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); + result = mSwapChain->ResizeBuffers(bufferCount, backbufferWidth, backbufferHeight, backbufferFormatInfo.texFormat, 0); if (FAILED(result)) { @@ -346,6 +364,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) return EGL_BAD_ALLOC; } } +#endif result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); ASSERT(SUCCEEDED(result)); @@ -399,6 +418,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap IDXGIFactory *factory = mRenderer->getDxgiFactory(); +#if !defined(ANGLE_PLATFORM_WINRT) DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; swapChainDesc.BufferDesc.Width = backbufferWidth; swapChainDesc.BufferDesc.Height = backbufferHeight; @@ -417,7 +437,37 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap swapChainDesc.Flags = 0; HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); +#else + IDXGIFactory2 *factory2; + HRESULT result = factory->QueryInterface(IID_PPV_ARGS(&factory2)); + ASSERT(SUCCEEDED(result)); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; + swapChainDesc.Width = 0; + swapChainDesc.Height = 0; + swapChainDesc.Format = backbufferFormatInfo.texFormat; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.Stereo = FALSE; + swapChainDesc.Flags = 0; +#if WINAPI_FAMILY==WINAPI_FAMILY_PC_APP + swapChainDesc.Scaling = DXGI_SCALING_NONE; + swapChainDesc.BufferCount = 2; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; +#elif WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP + swapChainDesc.BufferCount = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; +#endif + IDXGISwapChain1 *swapChain; + result = factory2->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); + mSwapChain = swapChain; + HRESULT hr = swapChain->GetDesc1(&swapChainDesc); + ASSERT(SUCCEEDED(hr)); + mViewportWidth = swapChainDesc.Width; + mViewportHeight = swapChainDesc.Height; +#endif if (FAILED(result)) { ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); @@ -513,7 +563,7 @@ void SwapChain11::initPassThroughResources() } // parameters should be validated/clamped by caller -EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags) { if (!mSwapChain) { @@ -544,10 +594,13 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) float u2 = (x + width) / float(mWidth); float v2 = (y + height) / float(mHeight); - d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1); - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); + const int rotateL = flags & SWAP_ROTATE_90; + const int rotateR = flags & SWAP_ROTATE_270; + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); deviceContext->Unmap(mQuadVB, 0); @@ -577,8 +630,8 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) D3D11_VIEWPORT viewport; viewport.TopLeftX = 0; viewport.TopLeftY = 0; - viewport.Width = mWidth; - viewport.Height = mHeight; + viewport.Width = mViewportWidth; + viewport.Height = mViewportHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; deviceContext->RSSetViewports(1, &viewport); diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h index fb0afd7..b30b785 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/SwapChain11.h @@ -19,13 +19,13 @@ class Renderer11; class SwapChain11 : public SwapChain { public: - SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle, + SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); virtual ~SwapChain11(); EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint flags); virtual void recreate(); virtual ID3D11Texture2D *getOffscreenTexture(); @@ -52,6 +52,8 @@ class SwapChain11 : public SwapChain Renderer11 *mRenderer; EGLint mHeight; EGLint mWidth; + EGLint mViewportWidth; + EGLint mViewportHeight; bool mAppCreatedShareHandle; unsigned int mSwapInterval; bool mPassThroughResourcesInit; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp index f702b79..0aeaabb 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.cpp @@ -238,7 +238,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI } // parameters should be validated/clamped by caller -EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint) { if (!mSwapChain) { diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h index 16a62bd..4d756f8 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/SwapChain9.h @@ -25,7 +25,7 @@ class SwapChain9 : public SwapChain EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); + virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height, EGLint); virtual void recreate(); virtual IDirect3DSurface9 *getRenderTarget(); -- 1.9.0.msysgit.0