From 211222be7016a9bec21386aa6d33ca12ff0f56f5 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 23 Feb 2011 09:18:00 -0800 Subject: [PATCH] Bug 626678. Try to handle docking station device resets better. r=bas,a=b Docking stations seem to cause DEVICELOST errors that never become DEVICERESET so we don't ever succeed in reseting the device. We now try to detect these situations and recreate the device. --- gfx/layers/d3d9/DeviceManagerD3D9.cpp | 29 ++++++++++++++++++++++++++- gfx/layers/d3d9/DeviceManagerD3D9.h | 3 +++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.cpp b/gfx/layers/d3d9/DeviceManagerD3D9.cpp index 65240730cc7..4fbac0ac20a 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.cpp +++ b/gfx/layers/d3d9/DeviceManagerD3D9.cpp @@ -332,6 +332,14 @@ DeviceManagerD3D9::Init() return false; } + /* Grab the associated HMONITOR so that we can find out + * if it changed later */ + D3DDEVICE_CREATION_PARAMETERS parameters; + if (FAILED(mDevice->GetCreationParameters(¶meters))) + return false; + mDeviceMonitor = mD3D9->GetAdapterMonitor(parameters.AdapterOrdinal); + + /* * Do some post device creation setup */ @@ -560,7 +568,26 @@ DeviceManagerD3D9::VerifyReadyForRendering() ++mDeviceResetCount; if (hr == D3DERR_DEVICELOST) { - return false; + /* It is not unusual for Reset to return DEVICELOST + * we're supposed to continue trying until we get + * DEVICENOTRESET and then Reset is supposed to succeed. + * Unfortunately, it seems like when we dock or undock + * DEVICELOST happens and we never get DEVICENOTRESET. */ + + HMONITOR hMonitorWindow; + hMonitorWindow = MonitorFromWindow(mFocusWnd, MONITOR_DEFAULTTOPRIMARY); + if (hMonitorWindow == mDeviceMonitor) { + /* The monitor has not changed. So, let's assume that the + * DEVICENOTRESET will be comming. */ + + /* jrmuizel: I'm not sure how to trigger this case. Usually, we get + * DEVICENOTRESET right away and Reset() succeeds without going through a + * set of DEVICELOSTs. This is presumeably because we don't call + * VerifyReadyForRendering when we don't have any reason to paint. + * Hopefully comparing HMONITORs is not overly aggressive. */ + return false; + } + /* otherwise fall through and recreate the device */ } if (FAILED(hr) || !CreateVertexBuffer()) { diff --git a/gfx/layers/d3d9/DeviceManagerD3D9.h b/gfx/layers/d3d9/DeviceManagerD3D9.h index bac0656ea76..90855c41483 100644 --- a/gfx/layers/d3d9/DeviceManagerD3D9.h +++ b/gfx/layers/d3d9/DeviceManagerD3D9.h @@ -233,6 +233,9 @@ private: */ HWND mFocusWnd; + /* we use this to help track if our device temporarily or permanently lost */ + HMONITOR mDeviceMonitor; + PRUint32 mDeviceResetCount; /* If this device supports dynamic textures */