Detect cross-process HWNDs and verify DXGI 1.2 exists in D3D11.

DXGI 1.2 is required to create a swap chain for a HWND owned by another
process.  This fix will allow us to fall back to creating a Renderer9 if
DXGI 1.2 is not available instead of failing to create the swap chain
later.

BUG=angle:562

Change-Id: I01b08ffb262bc3f9c86d244168df14eba52c5bdc
Reviewed-on: https://chromium-review.googlesource.com/186980
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/precompiled.h b/src/libGLESv2/precompiled.h
index fed6bc8..0253498 100644
--- a/src/libGLESv2/precompiled.h
+++ b/src/libGLESv2/precompiled.h
@@ -45,5 +45,6 @@
 #if defined(ANGLE_ENABLE_D3D11)
 #include <D3D11.h>
 #include <dxgi.h>
+#include <dxgi1_2.h>
 #include <D3Dcompiler.h>
 #endif // ANGLE_ENABLE_D3D11
diff --git a/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index f9c84dd..1030153 100644
--- a/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -33,6 +33,12 @@
 #include "libGLESv2/renderer/d3d11/PixelTransfer11.h"
 #include "libEGL/Display.h"
 
+// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
+// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
+#ifndef ANGLE_SKIP_DXGI_1_2_CHECK
+#define ANGLE_SKIP_DXGI_1_2_CHECK 0
+#endif
+
 #ifdef _DEBUG
 // this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
 // and conformance tests. to enable all warnings, remove this define.
@@ -184,6 +190,36 @@
         }
     }
 
+#if !ANGLE_SKIP_DXGI_1_2_CHECK
+    // 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;
+    HWND hwnd = WindowFromDC(mDc);
+    if (hwnd)
+    {
+        DWORD currentProcessId = GetCurrentProcessId();
+        DWORD wndProcessId;
+        GetWindowThreadProcessId(hwnd, &wndProcessId);
+        requireDXGI1_2 = (currentProcessId != wndProcessId);
+    }
+    else
+    {
+        requireDXGI1_2 = true;
+    }
+
+    if (requireDXGI1_2)
+    {
+        IDXGIDevice2 *dxgiDevice2 = NULL;
+        result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2);
+        if (FAILED(result))
+        {
+            ERR("DXGI 1.2 required to present to HWNDs owned by another process.\n");
+            return EGL_NOT_INITIALIZED;
+        }
+        SafeRelease(dxgiDevice2);
+    }
+#endif
+
     IDXGIDevice *dxgiDevice = NULL;
     result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
 
diff --git a/src/libGLESv2/renderer/d3d11/SwapChain11.cpp b/src/libGLESv2/renderer/d3d11/SwapChain11.cpp
index fcd6a6f..2721579 100644
--- a/src/libGLESv2/renderer/d3d11/SwapChain11.cpp
+++ b/src/libGLESv2/renderer/d3d11/SwapChain11.cpp
@@ -421,21 +421,7 @@
             }
             else
             {
-                // We cannot create a swap chain for an HWND that is owned by a different process on some versions of
-                // windows
-                DWORD currentProcessId = GetCurrentProcessId();
-                DWORD wndProcessId;
-                GetWindowThreadProcessId(mWindow, &wndProcessId);
-
-                if (currentProcessId != wndProcessId)
-                {
-                    ERR("Could not create swap chain, window owned by different process");
-                    return EGL_BAD_NATIVE_WINDOW;
-                }
-                else
-                {
-                    return EGL_BAD_ALLOC;
-                }
+                return EGL_BAD_ALLOC;
             }
         }