When CheckDeviceStats returns S_PRESENT_MODE_CHANGED, reset display mode and retest for device lost.

Unless the display mode is reset, CheckDeviceLost can keep returning
S_PRESENT_MODE_CHANGED, potentially masking a device lost on account of a GPU
hang, causing ANGLE to fail to report context lost.
Review URL: https://codereview.appspot.com/7381061

TRAC #22720

Signed-off-by: Geoff Lang
Signed-off-by: Shannon Woods
Author: Jamie Madill

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@2035 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index f5b672d..5cf54e0 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -2042,6 +2042,20 @@
     if (mDeviceEx)
     {
         status = mDeviceEx->CheckDeviceState(NULL);
+
+        if (status == S_PRESENT_MODE_CHANGED)
+        {
+            // Reset the device so that D3D stops reporting S_PRESENT_MODE_CHANGED. Otherwise it will report
+            // it continuously, potentially masking a lost device. D3D resources are not lost on a mode change with WDDM.
+            D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+            mDeviceEx->Reset(&presentParameters);
+
+            // Reset will not always cause the device loss to be reported so issue a dummy present.
+            mDeviceEx->Present(NULL, NULL, NULL, NULL);
+
+            // Retest the device status to see if the mode change really indicated a lost device.
+            status = mDeviceEx->CheckDeviceState(NULL);
+        }
     }
     else if (mDevice)
     {