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
git-svn-id: http://angleproject.googlecode.com/svn/trunk@1986 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/common/version.h b/src/common/version.h
index af92aa5..26ea517 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -1,7 +1,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
#define BUILD_VERSION 0
-#define BUILD_REVISION 1985
+#define BUILD_REVISION 1986
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/libEGL/Display.cpp b/src/libEGL/Display.cpp
index 0d40ad7..db88ffb 100644
--- a/src/libEGL/Display.cpp
+++ b/src/libEGL/Display.cpp
@@ -908,16 +908,32 @@
bool Display::testDeviceLost()
{
+ bool isLost = false;
+
if (mDeviceEx)
{
- return FAILED(mDeviceEx->CheckDeviceState(NULL));
+ HRESULT hr = mDeviceEx->CheckDeviceState(NULL);
+ if (hr == 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.
+ hr = mDeviceEx->CheckDeviceState(NULL);
+ }
+ isLost = FAILED(hr);
}
else if (mDevice)
{
- return FAILED(mDevice->TestCooperativeLevel());
+ isLost = FAILED(mDevice->TestCooperativeLevel());
}
- return false; // No device yet, so no reset required
+ return isLost;
}
bool Display::testDeviceResettable()